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

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"
13 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/signin/profile_oauth2_token_service.h" 13 #include "chrome/browser/signin/profile_oauth2_token_service.h"
15 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 14 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
16 #include "chrome/browser/signin/token_service.h" 15 #include "chrome/browser/signin/token_service.h"
17 #include "chrome/browser/signin/token_service_factory.h" 16 #include "chrome/browser/signin/token_service_factory.h"
18 #include "chrome/common/chrome_switches.h" 17 #include "chrome/common/chrome_switches.h"
19 #include "google_apis/gaia/gaia_constants.h" 18 #include "google_apis/gaia/gaia_constants.h"
20 #include "net/url_request/url_request_context_getter.h" 19 #include "net/url_request/url_request_context_getter.h"
21 20
22 namespace chromeos { 21 namespace chromeos {
23 22
24 OAuth2LoginManager::OAuth2LoginManager(OAuthLoginManager::Delegate* delegate) 23 OAuth2LoginManager::OAuth2LoginManager(Profile* user_profile)
25 : OAuthLoginManager(delegate), 24 : user_profile_(user_profile),
25 restore_strategy_(RESTORE_FROM_COOKIE_JAR),
26 state_(SESSION_RESTORE_NOT_STARTED),
26 loading_reported_(false) { 27 loading_reported_(false) {
28 ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_)->
29 AddObserver(this);
27 } 30 }
28 31
29 OAuth2LoginManager::~OAuth2LoginManager() { 32 OAuth2LoginManager::~OAuth2LoginManager() {
30 StopObservingRefreshToken(); 33 }
34
35 void OAuth2LoginManager::AddObserver(OAuth2LoginManager::Observer* observer) {
36 observer_list_.AddObserver(observer);
37 }
38
39 void OAuth2LoginManager::RemoveObserver(
40 OAuth2LoginManager::Observer* observer) {
41 observer_list_.RemoveObserver(observer);
31 } 42 }
32 43
33 void OAuth2LoginManager::RestoreSession( 44 void OAuth2LoginManager::RestoreSession(
34 Profile* user_profile,
35 net::URLRequestContextGetter* auth_request_context, 45 net::URLRequestContextGetter* auth_request_context,
36 SessionRestoreStrategy restore_strategy, 46 SessionRestoreStrategy restore_strategy,
37 const std::string& oauth2_refresh_token, 47 const std::string& oauth2_refresh_token,
38 const std::string& auth_code) { 48 const std::string& auth_code) {
39 StopObservingRefreshToken(); 49 DCHECK(user_profile_);
40 user_profile_ = user_profile;
41 auth_request_context_ = auth_request_context; 50 auth_request_context_ = auth_request_context;
42 state_ = OAuthLoginManager::SESSION_RESTORE_IN_PROGRESS;
43 restore_strategy_ = restore_strategy; 51 restore_strategy_ = restore_strategy;
44 refresh_token_ = oauth2_refresh_token; 52 refresh_token_ = oauth2_refresh_token;
45 auth_code_ = auth_code; 53 auth_code_ = auth_code;
46 54 session_restore_start_ = base::Time::Now();
47 // TODO(nkostylev): drop the previous fetchers if RestoreSession() is invoked 55 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_PREPARING);
48 // for a second Profile, when using multi-profiles. This avoids the DCHECKs
49 // below until OAuthLoginManager fully supports multi-profiles.
50 Stop();
51
52 ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_)->
53 AddObserver(this);
54
55 ContinueSessionRestore(); 56 ContinueSessionRestore();
56 } 57 }
57 58
58 void OAuth2LoginManager::ContinueSessionRestore() { 59 void OAuth2LoginManager::ContinueSessionRestore() {
59 if (restore_strategy_ == RESTORE_FROM_COOKIE_JAR || 60 if (restore_strategy_ == RESTORE_FROM_COOKIE_JAR ||
60 restore_strategy_ == RESTORE_FROM_AUTH_CODE) { 61 restore_strategy_ == RESTORE_FROM_AUTH_CODE) {
61 FetchOAuth2Tokens(); 62 FetchOAuth2Tokens();
62 return; 63 return;
63 } 64 }
64 65
65 // Save passed OAuth2 refresh token. 66 // Save passed OAuth2 refresh token.
66 if (restore_strategy_ == RESTORE_FROM_PASSED_OAUTH2_REFRESH_TOKEN) { 67 if (restore_strategy_ == RESTORE_FROM_PASSED_OAUTH2_REFRESH_TOKEN) {
67 DCHECK(!refresh_token_.empty()); 68 DCHECK(!refresh_token_.empty());
68 restore_strategy_ = RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN; 69 restore_strategy_ = RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN;
69 GaiaAuthConsumer::ClientOAuthResult oauth2_tokens; 70 GaiaAuthConsumer::ClientOAuthResult oauth2_tokens;
70 oauth2_tokens.refresh_token = refresh_token_; 71 oauth2_tokens.refresh_token = refresh_token_;
71 StoreOAuth2Tokens(oauth2_tokens); 72 StoreOAuth2Tokens(oauth2_tokens);
72 return; 73 return;
73 } 74 }
74 75
75 DCHECK(restore_strategy_ == RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN); 76 DCHECK(restore_strategy_ == RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN);
76 LoadAndVerifyOAuth2Tokens(); 77 LoadAndVerifyOAuth2Tokens();
77 } 78 }
78 79
79 void OAuth2LoginManager::Stop() { 80 void OAuth2LoginManager::Stop() {
80 oauth2_token_fetcher_.reset(); 81 oauth2_token_fetcher_.reset();
81 login_verifier_.reset(); 82 login_verifier_.reset();
82 } 83 }
83 84
85 bool OAuth2LoginManager::ShouldBlockTabLoading() {
86 return state_ == SESSION_RESTORE_PREPARING ||
87 state_ == SESSION_RESTORE_IN_PROGRESS;
88 }
89
84 void OAuth2LoginManager::OnRefreshTokenAvailable( 90 void OAuth2LoginManager::OnRefreshTokenAvailable(
85 const std::string& account_id) { 91 const std::string& account_id) {
92 if (state_ == SESSION_RESTORE_NOT_STARTED)
93 return;
94
86 // TODO(fgorski): Once ProfileOAuth2TokenService supports multi-login, make 95 // TODO(fgorski): Once ProfileOAuth2TokenService supports multi-login, make
87 // 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";
88 RestoreSessionCookies(); 98 RestoreSessionCookies();
89 } 99 }
90 100
91 TokenService* OAuth2LoginManager::SetupTokenService() { 101 TokenService* OAuth2LoginManager::SetupTokenService() {
92 TokenService* token_service = 102 TokenService* token_service =
93 TokenServiceFactory::GetForProfile(user_profile_); 103 TokenServiceFactory::GetForProfile(user_profile_);
94 return token_service; 104 return token_service;
95 } 105 }
96 106
97 void OAuth2LoginManager::StoreOAuth2Tokens( 107 void OAuth2LoginManager::StoreOAuth2Tokens(
(...skipping 18 matching lines...) Expand all
116 new OAuth2TokenFetcher(this, auth_request_context_.get())); 126 new OAuth2TokenFetcher(this, auth_request_context_.get()));
117 oauth2_token_fetcher_->StartExchangeFromCookies(); 127 oauth2_token_fetcher_->StartExchangeFromCookies();
118 } else if (restore_strategy_ == RESTORE_FROM_AUTH_CODE) { 128 } else if (restore_strategy_ == RESTORE_FROM_AUTH_CODE) {
119 DCHECK(!auth_code_.empty()); 129 DCHECK(!auth_code_.empty());
120 oauth2_token_fetcher_.reset( 130 oauth2_token_fetcher_.reset(
121 new OAuth2TokenFetcher(this, 131 new OAuth2TokenFetcher(this,
122 g_browser_process->system_request_context())); 132 g_browser_process->system_request_context()));
123 oauth2_token_fetcher_->StartExchangeFromAuthCode(auth_code_); 133 oauth2_token_fetcher_->StartExchangeFromAuthCode(auth_code_);
124 } else { 134 } else {
125 NOTREACHED(); 135 NOTREACHED();
136 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED);
126 } 137 }
127 } 138 }
128 139
129 void OAuth2LoginManager::OnOAuth2TokensAvailable( 140 void OAuth2LoginManager::OnOAuth2TokensAvailable(
130 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) { 141 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) {
131 LOG(INFO) << "OAuth2 tokens fetched"; 142 LOG(INFO) << "OAuth2 tokens fetched";
132 StoreOAuth2Tokens(oauth2_tokens); 143 StoreOAuth2Tokens(oauth2_tokens);
133 } 144 }
134 145
135 void OAuth2LoginManager::OnOAuth2TokensFetchFailed() { 146 void OAuth2LoginManager::OnOAuth2TokensFetchFailed() {
136 LOG(ERROR) << "OAuth2 tokens fetch failed!"; 147 LOG(ERROR) << "OAuth2 tokens fetch failed!";
137 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
138 UserManager::Get()->SaveUserOAuthStatus(
139 UserManager::Get()->GetLoggedInUser()->email(),
140 User::OAUTH2_TOKEN_STATUS_INVALID);
141 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", 148 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore",
142 SESSION_RESTORE_TOKEN_FETCH_FAILED, 149 SESSION_RESTORE_TOKEN_FETCH_FAILED,
143 SESSION_RESTORE_COUNT); 150 SESSION_RESTORE_COUNT);
151 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED);
144 } 152 }
145 153
146 void OAuth2LoginManager::RestoreSessionCookies() { 154 void OAuth2LoginManager::RestoreSessionCookies() {
147 DCHECK(!login_verifier_.get()); 155 DCHECK(!login_verifier_.get());
156 SetSessionRestoreState(SESSION_RESTORE_IN_PROGRESS);
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
164 void OAuth2LoginManager::Shutdown() {
165 ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_)->
166 RemoveObserver(this);
167 login_verifier_.reset();
168 oauth2_token_fetcher_.reset();
169 }
170
155 void OAuth2LoginManager::OnOAuthLoginSuccess( 171 void OAuth2LoginManager::OnOAuthLoginSuccess(
156 const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) { 172 const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) {
157 LOG(INFO) << "OAuth2 refresh token successfully exchanged for GAIA token."; 173 LOG(INFO) << "OAuth2 refresh token successfully exchanged for GAIA token.";
158 StartTokenService(gaia_credentials); 174 StartTokenService(gaia_credentials);
159 } 175 }
160 176
161 void OAuth2LoginManager::OnOAuthLoginFailure() { 177 void OAuth2LoginManager::OnOAuthLoginFailure() {
162 LOG(ERROR) << "OAuth2 refresh token verification failed!"; 178 LOG(ERROR) << "OAuth2 refresh token verification failed!";
163 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
164 UserManager::Get()->SaveUserOAuthStatus(
165 UserManager::Get()->GetLoggedInUser()->email(),
166 User::OAUTH2_TOKEN_STATUS_INVALID);
167 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", 179 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore",
168 SESSION_RESTORE_OAUTHLOGIN_FAILED, 180 SESSION_RESTORE_OAUTHLOGIN_FAILED,
169 SESSION_RESTORE_COUNT); 181 SESSION_RESTORE_COUNT);
170 delegate_->OnCompletedMergeSession(); 182 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED);
171 } 183 }
172 184
173 void OAuth2LoginManager::OnSessionMergeSuccess() { 185 void OAuth2LoginManager::OnSessionMergeSuccess() {
174 LOG(INFO) << "OAuth2 refresh and/or GAIA token verification succeeded."; 186 LOG(INFO) << "OAuth2 refresh and/or GAIA token verification succeeded.";
175 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
176 UserManager::Get()->SaveUserOAuthStatus(
177 UserManager::Get()->GetLoggedInUser()->email(),
178 User::OAUTH2_TOKEN_STATUS_VALID);
179 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", 187 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore",
180 SESSION_RESTORE_SUCCESS, 188 SESSION_RESTORE_SUCCESS,
181 SESSION_RESTORE_COUNT); 189 SESSION_RESTORE_COUNT);
182 delegate_->OnCompletedMergeSession(); 190 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_DONE);
183 } 191 }
184 192
185 void OAuth2LoginManager::OnSessionMergeFailure() { 193 void OAuth2LoginManager::OnSessionMergeFailure() {
186 LOG(ERROR) << "OAuth2 refresh and GAIA token verification failed!"; 194 LOG(ERROR) << "OAuth2 refresh and GAIA token verification failed!";
187 state_ = OAuthLoginManager::SESSION_RESTORE_DONE;
188 UserManager::Get()->SaveUserOAuthStatus(
189 UserManager::Get()->GetLoggedInUser()->email(),
190 User::OAUTH2_TOKEN_STATUS_INVALID);
191 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", 195 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore",
192 SESSION_RESTORE_MERGE_SESSION_FAILED, 196 SESSION_RESTORE_MERGE_SESSION_FAILED,
193 SESSION_RESTORE_COUNT); 197 SESSION_RESTORE_COUNT);
194 delegate_->OnCompletedMergeSession(); 198 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED);
195 } 199 }
196 200
197 void OAuth2LoginManager::StartTokenService( 201 void OAuth2LoginManager::StartTokenService(
198 const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) { 202 const GaiaAuthConsumer::ClientLoginResult& gaia_credentials) {
199 TokenService* token_service = SetupTokenService(); 203 TokenService* token_service = SetupTokenService();
200 token_service->UpdateCredentials(gaia_credentials); 204 token_service->UpdateCredentials(gaia_credentials);
201 CompleteAuthentication(); 205
206 FOR_EACH_OBSERVER(Observer, observer_list_,
207 OnSessionAuthenticated(user_profile_));
208
209 if (token_service->AreCredentialsValid())
210 token_service->StartFetchingTokens();
202 } 211 }
203 212
204 void OAuth2LoginManager::StopObservingRefreshToken() { 213 void OAuth2LoginManager::SetSessionRestoreState(
205 if (user_profile_) { 214 OAuth2LoginManager::SessionRestoreState state) {
206 ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_)-> 215 if (state_ == state)
207 RemoveObserver(this); 216 return;
208 } 217
218 state_ = state;
219 FOR_EACH_OBSERVER(Observer, observer_list_,
220 OnSessionRestoreStateChanged(user_profile_, state_));
221 }
222
223 void OAuth2LoginManager::SetSessionRestoreStartForTesting(
224 const base::Time& time) {
225 session_restore_start_ = time;
209 } 226 }
210 227
211 } // namespace chromeos 228 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/oauth2_login_manager.h ('k') | chrome/browser/chromeos/login/oauth2_login_manager_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698