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

Side by Side Diff: chrome/browser/chromeos/login/oauth2_login_manager.cc

Issue 23678007: OAuth2LoginManager+MergeSessionThrottle hardening, multi-profle support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/chromeos/login/user_manager.h" 12 #include "chrome/browser/chromeos/login/user_manager.h"
13 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/signin/profile_oauth2_token_service.h" 14 #include "chrome/browser/signin/profile_oauth2_token_service.h"
15 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 15 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
16 #include "chrome/browser/signin/token_service.h" 16 #include "chrome/browser/signin/token_service.h"
17 #include "chrome/browser/signin/token_service_factory.h" 17 #include "chrome/browser/signin/token_service_factory.h"
18 #include "chrome/common/chrome_switches.h" 18 #include "chrome/common/chrome_switches.h"
19 #include "google_apis/gaia/gaia_constants.h" 19 #include "google_apis/gaia/gaia_constants.h"
20 #include "net/url_request/url_request_context_getter.h" 20 #include "net/url_request/url_request_context_getter.h"
21 21
22 namespace chromeos { 22 namespace chromeos {
23 23
24 OAuth2LoginManager::OAuth2LoginManager(OAuthLoginManager::Delegate* delegate) 24 OAuth2LoginManager::OAuth2LoginManager(OAuthLoginManager::Delegate* delegate)
25 : OAuthLoginManager(delegate), 25 : OAuthLoginManager(delegate),
26 loading_reported_(false) { 26 loading_reported_(false),
27 session_start_signaled_(false) {
27 } 28 }
28 29
29 OAuth2LoginManager::~OAuth2LoginManager() { 30 OAuth2LoginManager::~OAuth2LoginManager() {
30 StopObservingRefreshToken(); 31 StopObservingRefreshToken();
31 } 32 }
32 33
33 void OAuth2LoginManager::RestoreSession( 34 void OAuth2LoginManager::RestoreSession(
34 Profile* user_profile, 35 Profile* user_profile,
35 net::URLRequestContextGetter* auth_request_context, 36 net::URLRequestContextGetter* auth_request_context,
36 SessionRestoreStrategy restore_strategy, 37 SessionRestoreStrategy restore_strategy,
37 const std::string& oauth2_refresh_token, 38 const std::string& oauth2_refresh_token,
38 const std::string& auth_code) { 39 const std::string& auth_code) {
39 StopObservingRefreshToken(); 40 StopObservingRefreshToken();
40 user_profile_ = user_profile; 41 user_profile_ = user_profile;
41 auth_request_context_ = auth_request_context; 42 auth_request_context_ = auth_request_context;
42 state_ = OAuthLoginManager::SESSION_RESTORE_IN_PROGRESS; 43 state_ = OAuthLoginManager::SESSION_RESTORE_IN_PROGRESS;
43 restore_strategy_ = restore_strategy; 44 restore_strategy_ = restore_strategy;
44 refresh_token_ = oauth2_refresh_token; 45 refresh_token_ = oauth2_refresh_token;
45 auth_code_ = auth_code; 46 auth_code_ = auth_code;
46 47
48 DCHECK(!session_start_signaled_);
49 session_start_signaled_ = false;
50
47 // TODO(nkostylev): drop the previous fetchers if RestoreSession() is invoked 51 // TODO(nkostylev): drop the previous fetchers if RestoreSession() is invoked
48 // for a second Profile, when using multi-profiles. This avoids the DCHECKs 52 // for a second Profile, when using multi-profiles. This avoids the DCHECKs
49 // below until OAuthLoginManager fully supports multi-profiles. 53 // below until OAuthLoginManager fully supports multi-profiles.
50 Stop(); 54 Stop();
51 55
52 ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_)-> 56 ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_)->
53 AddObserver(this); 57 AddObserver(this);
54 58
55 ContinueSessionRestore(); 59 ContinueSessionRestore();
56 } 60 }
(...skipping 21 matching lines...) Expand all
78 82
79 void OAuth2LoginManager::Stop() { 83 void OAuth2LoginManager::Stop() {
80 oauth2_token_fetcher_.reset(); 84 oauth2_token_fetcher_.reset();
81 login_verifier_.reset(); 85 login_verifier_.reset();
82 } 86 }
83 87
84 void OAuth2LoginManager::OnRefreshTokenAvailable( 88 void OAuth2LoginManager::OnRefreshTokenAvailable(
85 const std::string& account_id) { 89 const std::string& account_id) {
86 // TODO(fgorski): Once ProfileOAuth2TokenService supports multi-login, make 90 // TODO(fgorski): Once ProfileOAuth2TokenService supports multi-login, make
87 // sure to restore session cookies in the context of the correct account_id. 91 // sure to restore session cookies in the context of the correct account_id.
92 LOG(INFO) << "OnRefreshTokenAvailable";
88 RestoreSessionCookies(); 93 RestoreSessionCookies();
89 } 94 }
90 95
91 TokenService* OAuth2LoginManager::SetupTokenService() { 96 TokenService* OAuth2LoginManager::SetupTokenService() {
92 TokenService* token_service = 97 TokenService* token_service =
93 TokenServiceFactory::GetForProfile(user_profile_); 98 TokenServiceFactory::GetForProfile(user_profile_);
94 return token_service; 99 return token_service;
95 } 100 }
96 101
97 void OAuth2LoginManager::StoreOAuth2Tokens( 102 void OAuth2LoginManager::StoreOAuth2Tokens(
98 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) { 103 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) {
99 TokenService* token_service = SetupTokenService(); 104 TokenService* token_service = SetupTokenService();
100 token_service->UpdateCredentialsWithOAuth2(oauth2_tokens); 105 token_service->UpdateCredentialsWithOAuth2(oauth2_tokens);
101 } 106 }
102 107
103 void OAuth2LoginManager::LoadAndVerifyOAuth2Tokens() { 108 void OAuth2LoginManager::LoadAndVerifyOAuth2Tokens() {
104 // If we have no cookies, try to load saved OAuth2 token from TokenService. 109 // If we have no cookies, try to load saved OAuth2 token from TokenService.
105 TokenService* token_service = SetupTokenService(); 110 TokenService* token_service = SetupTokenService();
106 token_service->Initialize(GaiaConstants::kChromeSource, user_profile_); 111 token_service->Initialize(GaiaConstants::kChromeSource, user_profile_);
107 token_service->LoadTokensFromDB(); 112 token_service->LoadTokensFromDB();
108 } 113 }
109 114
110 void OAuth2LoginManager::FetchOAuth2Tokens() { 115 void OAuth2LoginManager::FetchOAuth2Tokens() {
111 DCHECK(auth_request_context_.get()); 116 DCHECK(auth_request_context_.get());
117 SignalMergeSessionStart();
118
112 // If we have authenticated cookie jar, get OAuth1 token first, then fetch 119 // If we have authenticated cookie jar, get OAuth1 token first, then fetch
113 // SID/LSID cookies through OAuthLogin call. 120 // SID/LSID cookies through OAuthLogin call.
114 if (restore_strategy_ == RESTORE_FROM_COOKIE_JAR) { 121 if (restore_strategy_ == RESTORE_FROM_COOKIE_JAR) {
115 oauth2_token_fetcher_.reset( 122 oauth2_token_fetcher_.reset(
116 new OAuth2TokenFetcher(this, auth_request_context_.get())); 123 new OAuth2TokenFetcher(this, auth_request_context_.get()));
117 oauth2_token_fetcher_->StartExchangeFromCookies(); 124 oauth2_token_fetcher_->StartExchangeFromCookies();
118 } else if (restore_strategy_ == RESTORE_FROM_AUTH_CODE) { 125 } else if (restore_strategy_ == RESTORE_FROM_AUTH_CODE) {
119 DCHECK(!auth_code_.empty()); 126 DCHECK(!auth_code_.empty());
120 oauth2_token_fetcher_.reset( 127 oauth2_token_fetcher_.reset(
121 new OAuth2TokenFetcher(this, 128 new OAuth2TokenFetcher(this,
122 g_browser_process->system_request_context())); 129 g_browser_process->system_request_context()));
123 oauth2_token_fetcher_->StartExchangeFromAuthCode(auth_code_); 130 oauth2_token_fetcher_->StartExchangeFromAuthCode(auth_code_);
124 } else { 131 } else {
125 NOTREACHED(); 132 NOTREACHED();
133 SignalMergeSessionEnd();
126 } 134 }
127 } 135 }
128 136
129 void OAuth2LoginManager::OnOAuth2TokensAvailable( 137 void OAuth2LoginManager::OnOAuth2TokensAvailable(
130 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) { 138 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) {
131 LOG(INFO) << "OAuth2 tokens fetched"; 139 LOG(INFO) << "OAuth2 tokens fetched";
132 StoreOAuth2Tokens(oauth2_tokens); 140 StoreOAuth2Tokens(oauth2_tokens);
133 } 141 }
134 142
135 void OAuth2LoginManager::OnOAuth2TokensFetchFailed() { 143 void OAuth2LoginManager::OnOAuth2TokensFetchFailed() {
136 LOG(ERROR) << "OAuth2 tokens fetch failed!"; 144 LOG(ERROR) << "OAuth2 tokens fetch failed!";
137 state_ = OAuthLoginManager::SESSION_RESTORE_DONE; 145 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
138 UserManager::Get()->SaveUserOAuthStatus( 146 UserManager::Get()->SaveUserOAuthStatus(
139 UserManager::Get()->GetLoggedInUser()->email(), 147 UserManager::Get()->GetLoggedInUser()->email(),
140 User::OAUTH2_TOKEN_STATUS_INVALID); 148 User::OAUTH2_TOKEN_STATUS_INVALID);
141 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", 149 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore",
142 SESSION_RESTORE_TOKEN_FETCH_FAILED, 150 SESSION_RESTORE_TOKEN_FETCH_FAILED,
143 SESSION_RESTORE_COUNT); 151 SESSION_RESTORE_COUNT);
144 } 152 }
145 153
146 void OAuth2LoginManager::RestoreSessionCookies() { 154 void OAuth2LoginManager::RestoreSessionCookies() {
147 DCHECK(!login_verifier_.get()); 155 DCHECK(!login_verifier_.get());
156 SignalMergeSessionStart();
148 login_verifier_.reset( 157 login_verifier_.reset(
149 new OAuth2LoginVerifier(this, 158 new OAuth2LoginVerifier(this,
150 g_browser_process->system_request_context(), 159 g_browser_process->system_request_context(),
151 user_profile_->GetRequestContext())); 160 user_profile_->GetRequestContext()));
152 login_verifier_->VerifyProfileTokens(user_profile_); 161 login_verifier_->VerifyProfileTokens(user_profile_);
153 } 162 }
154 163
155 void OAuth2LoginManager::OnOAuthLoginSuccess( 164 void OAuth2LoginManager::OnOAuthLoginSuccess(
156 const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) { 165 const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) {
157 LOG(INFO) << "OAuth2 refresh token successfully exchanged for GAIA token."; 166 LOG(INFO) << "OAuth2 refresh token successfully exchanged for GAIA token.";
158 StartTokenService(gaia_credentials); 167 StartTokenService(gaia_credentials);
159 } 168 }
160 169
161 void OAuth2LoginManager::OnOAuthLoginFailure() { 170 void OAuth2LoginManager::OnOAuthLoginFailure() {
162 LOG(ERROR) << "OAuth2 refresh token verification failed!"; 171 LOG(ERROR) << "OAuth2 refresh token verification failed!";
163 state_ = OAuthLoginManager::SESSION_RESTORE_DONE; 172 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
164 UserManager::Get()->SaveUserOAuthStatus( 173 UserManager::Get()->SaveUserOAuthStatus(
165 UserManager::Get()->GetLoggedInUser()->email(), 174 UserManager::Get()->GetLoggedInUser()->email(),
166 User::OAUTH2_TOKEN_STATUS_INVALID); 175 User::OAUTH2_TOKEN_STATUS_INVALID);
167 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", 176 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore",
168 SESSION_RESTORE_OAUTHLOGIN_FAILED, 177 SESSION_RESTORE_OAUTHLOGIN_FAILED,
169 SESSION_RESTORE_COUNT); 178 SESSION_RESTORE_COUNT);
170 delegate_->OnCompletedMergeSession(); 179 SignalMergeSessionEnd();
171 } 180 }
172 181
173 void OAuth2LoginManager::OnSessionMergeSuccess() { 182 void OAuth2LoginManager::OnSessionMergeSuccess() {
174 LOG(INFO) << "OAuth2 refresh and/or GAIA token verification succeeded."; 183 LOG(INFO) << "OAuth2 refresh and/or GAIA token verification succeeded.";
175 state_ = OAuthLoginManager::SESSION_RESTORE_DONE; 184 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
176 UserManager::Get()->SaveUserOAuthStatus( 185 UserManager::Get()->SaveUserOAuthStatus(
177 UserManager::Get()->GetLoggedInUser()->email(), 186 UserManager::Get()->GetLoggedInUser()->email(),
178 User::OAUTH2_TOKEN_STATUS_VALID); 187 User::OAUTH2_TOKEN_STATUS_VALID);
179 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", 188 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore",
180 SESSION_RESTORE_SUCCESS, 189 SESSION_RESTORE_SUCCESS,
181 SESSION_RESTORE_COUNT); 190 SESSION_RESTORE_COUNT);
182 delegate_->OnCompletedMergeSession(); 191 SignalMergeSessionEnd();
183 } 192 }
184 193
185 void OAuth2LoginManager::OnSessionMergeFailure() { 194 void OAuth2LoginManager::OnSessionMergeFailure() {
186 LOG(ERROR) << "OAuth2 refresh and GAIA token verification failed!"; 195 LOG(ERROR) << "OAuth2 refresh and GAIA token verification failed!";
187 state_ = OAuthLoginManager::SESSION_RESTORE_DONE; 196 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
188 UserManager::Get()->SaveUserOAuthStatus( 197 UserManager::Get()->SaveUserOAuthStatus(
189 UserManager::Get()->GetLoggedInUser()->email(), 198 UserManager::Get()->GetLoggedInUser()->email(),
190 User::OAUTH2_TOKEN_STATUS_INVALID); 199 User::OAUTH2_TOKEN_STATUS_INVALID);
191 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", 200 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore",
192 SESSION_RESTORE_MERGE_SESSION_FAILED, 201 SESSION_RESTORE_MERGE_SESSION_FAILED,
193 SESSION_RESTORE_COUNT); 202 SESSION_RESTORE_COUNT);
194 delegate_->OnCompletedMergeSession(); 203 SignalMergeSessionEnd();
195 } 204 }
196 205
197 void OAuth2LoginManager::StartTokenService( 206 void OAuth2LoginManager::StartTokenService(
198 const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) { 207 const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) {
199 TokenService* token_service = SetupTokenService(); 208 TokenService* token_service = SetupTokenService();
200 token_service->UpdateCredentials(gaia_credentials); 209 token_service->UpdateCredentials(gaia_credentials);
201 CompleteAuthentication(); 210 CompleteAuthentication();
202 } 211 }
203 212
204 void OAuth2LoginManager::StopObservingRefreshToken() { 213 void OAuth2LoginManager::StopObservingRefreshToken() {
205 if (user_profile_) { 214 if (user_profile_) {
206 ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_)-> 215 ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_)->
207 RemoveObserver(this); 216 RemoveObserver(this);
208 } 217 }
209 } 218 }
210 219
220 void OAuth2LoginManager::SignalMergeSessionStart() {
221 if (session_start_signaled_)
222 return;
223
224 delegate_->OnStartMergeSession(user_profile_);
225 session_start_signaled_ = true;
226 }
227
228 void OAuth2LoginManager::SignalMergeSessionEnd() {
229 delegate_->OnCompletedMergeSession();
230 }
231
211 } // namespace chromeos 232 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698