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

Side by Side Diff: chrome/browser/signin/signin_manager.cc

Issue 12502017: signin: pull basic SigninManager functionality into new SigninManagerBase class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: deal with new enterprise_platform_keys_private_api Created 7 years, 8 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
« no previous file with comments | « chrome/browser/signin/signin_manager.h ('k') | chrome/browser/signin/signin_manager_base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/signin/signin_manager.h" 5 #include "chrome/browser/signin/signin_manager.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 29 matching lines...) Expand all
40 #include "content/public/browser/notification_service.h" 40 #include "content/public/browser/notification_service.h"
41 #include "content/public/browser/render_process_host.h" 41 #include "content/public/browser/render_process_host.h"
42 #include "google_apis/gaia/gaia_auth_fetcher.h" 42 #include "google_apis/gaia/gaia_auth_fetcher.h"
43 #include "google_apis/gaia/gaia_auth_util.h" 43 #include "google_apis/gaia/gaia_auth_util.h"
44 #include "google_apis/gaia/gaia_constants.h" 44 #include "google_apis/gaia/gaia_constants.h"
45 #include "google_apis/gaia/gaia_urls.h" 45 #include "google_apis/gaia/gaia_urls.h"
46 #include "net/base/escape.h" 46 #include "net/base/escape.h"
47 #include "net/url_request/url_request_context.h" 47 #include "net/url_request/url_request_context.h"
48 #include "third_party/icu/public/i18n/unicode/regex.h" 48 #include "third_party/icu/public/i18n/unicode/regex.h"
49 49
50 #if defined(ENABLE_CONFIGURATION_POLICY) && !defined(OS_CHROMEOS) 50 #if defined(ENABLE_CONFIGURATION_POLICY)
51 #include "chrome/browser/policy/cloud/user_policy_signin_service.h" 51 #include "chrome/browser/policy/cloud/user_policy_signin_service.h"
52 #include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h" 52 #include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h"
53 #endif 53 #endif
54 54
55 using namespace signin_internals_util; 55 using namespace signin_internals_util;
56 56
57 using content::BrowserThread; 57 using content::BrowserThread;
58 58
59 namespace { 59 namespace {
60 60
61 const char kGetInfoDisplayEmailKey[] = "displayEmail"; 61 const char kGetInfoDisplayEmailKey[] = "displayEmail";
62 const char kGetInfoEmailKey[] = "email"; 62 const char kGetInfoEmailKey[] = "email";
63 63
64 const char kGoogleAccountsUrl[] = "https://accounts.google.com";
65
66 const int kInvalidProcessId = -1; 64 const int kInvalidProcessId = -1;
67 65
68 const char kChromiumSyncService[] = "service=chromiumsync"; 66 const char kChromiumSyncService[] = "service=chromiumsync";
69 67
70 } // namespace 68 } // namespace
71 69
72 // Under the covers, we use a dummy chrome-extension ID to serve the purposes 70 // Under the covers, we use a dummy chrome-extension ID to serve the purposes
73 // outlined in the .h file comment for this string. 71 // outlined in the .h file comment for this string.
74 const char* SigninManager::kChromeSigninEffectiveSite = 72 const char* SigninManager::kChromeSigninEffectiveSite =
75 "chrome-extension://acfccoigjajmmgbhpfbjnpckhjjegnih"; 73 "chrome-extension://acfccoigjajmmgbhpfbjnpckhjjegnih";
(...skipping 11 matching lines...) Expand all
87 return false; 85 return false;
88 86
89 // Any login UI URLs with signin=chromiumsync should be considered a web 87 // Any login UI URLs with signin=chromiumsync should be considered a web
90 // URL (relies on GAIA keeping the "service=chromiumsync" query string 88 // URL (relies on GAIA keeping the "service=chromiumsync" query string
91 // fragment present even when embedding inside a "continue" parameter). 89 // fragment present even when embedding inside a "continue" parameter).
92 return net::UnescapeURLComponent( 90 return net::UnescapeURLComponent(
93 url.query(), net::UnescapeRule::URL_SPECIAL_CHARS) 91 url.query(), net::UnescapeRule::URL_SPECIAL_CHARS)
94 .find(kChromiumSyncService) != std::string::npos; 92 .find(kChromiumSyncService) != std::string::npos;
95 } 93 }
96 94
97 // static
98 bool SigninManager::AreSigninCookiesAllowed(Profile* profile) {
99 CookieSettings* cookie_settings =
100 CookieSettings::Factory::GetForProfile(profile);
101 return AreSigninCookiesAllowed(cookie_settings);
102 }
103
104 // static
105 bool SigninManager::AreSigninCookiesAllowed(CookieSettings* cookie_settings) {
106 return cookie_settings &&
107 cookie_settings->IsSettingCookieAllowed(GURL(kGoogleAccountsUrl),
108 GURL(kGoogleAccountsUrl));
109 }
110
111 // static
112 bool SigninManager::IsAllowedUsername(const std::string& username,
113 const std::string& policy) {
114 if (policy.empty())
115 return true;
116
117 // Patterns like "*@foo.com" are not accepted by our regex engine (since they
118 // are not valid regular expressions - they should instead be ".*@foo.com").
119 // For convenience, detect these patterns and insert a "." character at the
120 // front.
121 string16 pattern = UTF8ToUTF16(policy);
122 if (pattern[0] == L'*')
123 pattern.insert(pattern.begin(), L'.');
124
125 // See if the username matches the policy-provided pattern.
126 UErrorCode status = U_ZERO_ERROR;
127 const icu::UnicodeString icu_pattern(pattern.data(), pattern.length());
128 icu::RegexMatcher matcher(icu_pattern, UREGEX_CASE_INSENSITIVE, status);
129 if (!U_SUCCESS(status)) {
130 LOG(ERROR) << "Invalid login regex: " << pattern << ", status: " << status;
131 // If an invalid pattern is provided, then prohibit *all* logins (better to
132 // break signin than to quietly allow users to sign in).
133 return false;
134 }
135 string16 username16 = UTF8ToUTF16(username);
136 icu::UnicodeString icu_input(username16.data(), username16.length());
137 matcher.reset(icu_input);
138 status = U_ZERO_ERROR;
139 UBool match = matcher.matches(status);
140 DCHECK(U_SUCCESS(status));
141 return !!match; // !! == convert from UBool to bool.
142 }
143
144 SigninManager::SigninManager() 95 SigninManager::SigninManager()
145 : profile_(NULL), 96 : prohibit_signout_(false),
146 prohibit_signout_(false),
147 had_two_factor_error_(false), 97 had_two_factor_error_(false),
148 type_(SIGNIN_TYPE_NONE), 98 type_(SIGNIN_TYPE_NONE),
149 weak_pointer_factory_(this), 99 weak_pointer_factory_(this),
150 signin_process_id_(kInvalidProcessId) { 100 signin_process_id_(kInvalidProcessId) {
151 } 101 }
152 102
153 void SigninManager::SetSigninProcess(int process_id) { 103 void SigninManager::SetSigninProcess(int process_id) {
154 if (process_id == signin_process_id_) 104 if (process_id == signin_process_id_)
155 return; 105 return;
156 DLOG_IF(WARNING, signin_process_id_ != kInvalidProcessId) << 106 DLOG_IF(WARNING, signin_process_id_ != kInvalidProcessId) <<
157 "Replacing in-use signin process."; 107 "Replacing in-use signin process.";
158 signin_process_id_ = process_id; 108 signin_process_id_ = process_id;
159 const content::RenderProcessHost* process = 109 const content::RenderProcessHost* process =
160 content::RenderProcessHost::FromID(process_id); 110 content::RenderProcessHost::FromID(process_id);
161 DCHECK(process); 111 DCHECK(process);
162 registrar_.Add(this, 112 registrar_.Add(this,
163 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 113 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
164 content::Source<content::RenderProcessHost>(process)); 114 content::Source<content::RenderProcessHost>(process));
165 } 115 }
166 116
167 bool SigninManager::IsSigninProcess(int process_id) const { 117 bool SigninManager::IsSigninProcess(int process_id) const {
168 return process_id == signin_process_id_; 118 return process_id == signin_process_id_;
169 } 119 }
170 120
171 bool SigninManager::HasSigninProcess() const { 121 bool SigninManager::HasSigninProcess() const {
172 return signin_process_id_ != kInvalidProcessId; 122 return signin_process_id_ != kInvalidProcessId;
173 } 123 }
174 124
175 SigninManager::~SigninManager() { 125 SigninManager::~SigninManager() {
176 DCHECK(!signin_global_error_.get()) <<
177 "SigninManager::Initialize called but not SigninManager::Shutdown";
178 } 126 }
179 127
180 void SigninManager::Initialize(Profile* profile) { 128 void SigninManager::InitTokenService() {
181 // Should never call Initialize() twice. 129 SigninManagerBase::InitTokenService();
182 DCHECK(!IsInitialized());
183 profile_ = profile;
184 signin_global_error_.reset(new SigninGlobalError(this, profile));
185 GlobalErrorServiceFactory::GetForProfile(profile_)->AddGlobalError(
186 signin_global_error_.get());
187 PrefService* local_state = g_browser_process->local_state();
188 // local_state can be null during unit tests.
189 if (local_state) {
190 local_state_pref_registrar_.Init(local_state);
191 local_state_pref_registrar_.Add(
192 prefs::kGoogleServicesUsernamePattern,
193 base::Bind(&SigninManager::OnGoogleServicesUsernamePatternChanged,
194 weak_pointer_factory_.GetWeakPtr()));
195 }
196 signin_allowed_.Init(prefs::kSigninAllowed, profile_->GetPrefs(),
197 base::Bind(&SigninManager::OnSigninAllowedPrefChanged,
198 base::Unretained(this)));
199
200 // If the user is clearing the token service from the command line, then
201 // clear their login info also (not valid to be logged in without any
202 // tokens).
203 CommandLine* cmd_line = CommandLine::ForCurrentProcess();
204 if (cmd_line->HasSwitch(switches::kClearTokenService))
205 profile->GetPrefs()->ClearPref(prefs::kGoogleServicesUsername);
206
207 std::string user = profile_->GetPrefs()->GetString(
208 prefs::kGoogleServicesUsername);
209 if (!user.empty())
210 SetAuthenticatedUsername(user);
211 // TokenService can be null for unit tests.
212 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 130 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
213 if (token_service) { 131 if (token_service && !GetAuthenticatedUsername().empty())
214 token_service->Initialize(GaiaConstants::kChromeSource, profile_); 132 token_service->LoadTokensFromDB();
215 // ChromeOS will kick off TokenService::LoadTokensFromDB from
216 // OAuthLoginManager once the rest of the Profile is fully initialized.
217 // Starting it from here would cause OAuthLoginManager mismatch the origin
218 // of OAuth2 tokens.
219 #if !defined(OS_CHROMEOS)
220 if (!authenticated_username_.empty()) {
221 token_service->LoadTokensFromDB();
222 }
223 #endif
224 }
225 if ((!user.empty() && !IsAllowedUsername(user)) || !IsSigninAllowed()) {
226 // User is signed in, but the username is invalid - the administrator must
227 // have changed the policy since the last signin, so sign out the user.
228 SignOut();
229 }
230 }
231
232 bool SigninManager::IsInitialized() const {
233 return profile_ != NULL;
234 }
235
236 bool SigninManager::IsAllowedUsername(const std::string& username) const {
237 PrefService* local_state = g_browser_process->local_state();
238 if (!local_state)
239 return true; // In a unit test with no local state - all names are allowed.
240
241 std::string pattern = local_state->GetString(
242 prefs::kGoogleServicesUsernamePattern);
243 return IsAllowedUsername(username, pattern);
244 }
245
246 bool SigninManager::IsSigninAllowed() const {
247 return signin_allowed_.GetValue();
248 }
249
250 // static
251 bool SigninManager::IsSigninAllowedOnIOThread(ProfileIOData* io_data) {
252 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
253 return io_data->signin_allowed()->GetValue();
254 } 133 }
255 134
256 void SigninManager::CleanupNotificationRegistration() { 135 void SigninManager::CleanupNotificationRegistration() {
257 #if !defined(OS_CHROMEOS)
258 content::Source<TokenService> token_service( 136 content::Source<TokenService> token_service(
259 TokenServiceFactory::GetForProfile(profile_)); 137 TokenServiceFactory::GetForProfile(profile_));
260 if (registrar_.IsRegistered(this, 138 if (registrar_.IsRegistered(this,
261 chrome::NOTIFICATION_TOKEN_AVAILABLE, 139 chrome::NOTIFICATION_TOKEN_AVAILABLE,
262 token_service)) { 140 token_service)) {
263 registrar_.Remove(this, 141 registrar_.Remove(this,
264 chrome::NOTIFICATION_TOKEN_AVAILABLE, 142 chrome::NOTIFICATION_TOKEN_AVAILABLE,
265 token_service); 143 token_service);
266 } 144 }
267 #endif
268 }
269
270 const std::string& SigninManager::GetAuthenticatedUsername() const {
271 return authenticated_username_;
272 }
273
274 void SigninManager::SetAuthenticatedUsername(const std::string& username) {
275 if (!authenticated_username_.empty()) {
276 DLOG_IF(ERROR, username != authenticated_username_) <<
277 "Tried to change the authenticated username to something different: " <<
278 "Current: " << authenticated_username_ << ", New: " << username;
279 return;
280 }
281 authenticated_username_ = username;
282 // TODO(tim): We could go further in ensuring kGoogleServicesUsername and
283 // authenticated_username_ are consistent once established (e.g. remove
284 // authenticated_username_ altogether). Bug 107160.
285
286 NotifyDiagnosticsObservers(USERNAME, username);
287
288 // Go ahead and update the last signed in username here as well. Once a
289 // user is signed in the two preferences should match. Doing it here as
290 // opposed to on signin allows us to catch the upgrade scenario.
291 profile_->GetPrefs()->SetString(prefs::kGoogleServicesLastUsername, username);
292 } 145 }
293 146
294 std::string SigninManager::SigninTypeToString( 147 std::string SigninManager::SigninTypeToString(
295 SigninManager::SigninType type) { 148 SigninManager::SigninType type) {
296 switch (type) { 149 switch (type) {
297 case SIGNIN_TYPE_NONE: 150 case SIGNIN_TYPE_NONE:
298 return "No Signin"; 151 return "No Signin";
299 case SIGNIN_TYPE_CLIENT_LOGIN: 152 case SIGNIN_TYPE_CLIENT_LOGIN:
300 return "Client Login"; 153 return "Client Login";
301 case SIGNIN_TYPE_WITH_CREDENTIALS: 154 case SIGNIN_TYPE_WITH_CREDENTIALS:
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 192
340 NotifyDiagnosticsObservers(SIGNIN_TYPE, SigninTypeToString(type)); 193 NotifyDiagnosticsObservers(SIGNIN_TYPE, SigninTypeToString(type));
341 return true; 194 return true;
342 } 195 }
343 196
344 // Users must always sign out before they sign in again. 197 // Users must always sign out before they sign in again.
345 void SigninManager::StartSignIn(const std::string& username, 198 void SigninManager::StartSignIn(const std::string& username,
346 const std::string& password, 199 const std::string& password,
347 const std::string& login_token, 200 const std::string& login_token,
348 const std::string& login_captcha) { 201 const std::string& login_captcha) {
349 DCHECK(authenticated_username_.empty() || 202 DCHECK(GetAuthenticatedUsername().empty() ||
350 gaia::AreEmailsSame(username, authenticated_username_)); 203 gaia::AreEmailsSame(username, GetAuthenticatedUsername()));
351 204
352 if (!PrepareForSignin(SIGNIN_TYPE_CLIENT_LOGIN, username, password)) 205 if (!PrepareForSignin(SIGNIN_TYPE_CLIENT_LOGIN, username, password))
353 return; 206 return;
354 207
355 client_login_->StartClientLogin(username, 208 client_login_->StartClientLogin(username,
356 password, 209 password,
357 "", 210 "",
358 login_token, 211 login_token,
359 login_captcha, 212 login_captcha,
360 GaiaAuthFetcher::HostedAccountsNotAllowed); 213 GaiaAuthFetcher::HostedAccountsNotAllowed);
361 214
362 // Register for token availability. The signin manager will pre-login the 215 // Register for token availability. The signin manager will pre-login the
363 // user when the GAIA service token is ready for use. Only do this if we 216 // user when the GAIA service token is ready for use.
364 // are not running in ChomiumOS, since it handles pre-login itself, and if
365 // cookies are not disabled for Google accounts.
366 #if !defined(OS_CHROMEOS)
367 if (AreSigninCookiesAllowed(profile_)) { 217 if (AreSigninCookiesAllowed(profile_)) {
368 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 218 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
369 registrar_.Add(this, 219 registrar_.Add(this,
370 chrome::NOTIFICATION_TOKEN_AVAILABLE, 220 chrome::NOTIFICATION_TOKEN_AVAILABLE,
371 content::Source<TokenService>(token_service)); 221 content::Source<TokenService>(token_service));
372 } 222 }
373 #endif
374 } 223 }
375 224
376 void SigninManager::ProvideSecondFactorAccessCode( 225 void SigninManager::ProvideSecondFactorAccessCode(
377 const std::string& access_code) { 226 const std::string& access_code) {
378 DCHECK(!possibly_invalid_username_.empty() && !password_.empty() && 227 DCHECK(!possibly_invalid_username_.empty() && !password_.empty() &&
379 last_result_.data.empty()); 228 last_result_.data.empty());
380 DCHECK(type_ == SIGNIN_TYPE_CLIENT_LOGIN); 229 DCHECK(type_ == SIGNIN_TYPE_CLIENT_LOGIN);
381 230
382 client_login_.reset(new GaiaAuthFetcher(this, 231 client_login_.reset(new GaiaAuthFetcher(this,
383 GaiaConstants::kChromeSource, 232 GaiaConstants::kChromeSource,
384 profile_->GetRequestContext())); 233 profile_->GetRequestContext()));
385 client_login_->StartClientLogin(possibly_invalid_username_, 234 client_login_->StartClientLogin(possibly_invalid_username_,
386 access_code, 235 access_code,
387 "", 236 "",
388 std::string(), 237 std::string(),
389 std::string(), 238 std::string(),
390 GaiaAuthFetcher::HostedAccountsNotAllowed); 239 GaiaAuthFetcher::HostedAccountsNotAllowed);
391 } 240 }
392 241
393 void SigninManager::StartSignInWithCredentials(const std::string& session_index, 242 void SigninManager::StartSignInWithCredentials(const std::string& session_index,
394 const std::string& username, 243 const std::string& username,
395 const std::string& password) { 244 const std::string& password) {
396 DCHECK(authenticated_username_.empty() || 245 DCHECK(GetAuthenticatedUsername().empty() ||
397 gaia::AreEmailsSame(username, authenticated_username_)); 246 gaia::AreEmailsSame(username, GetAuthenticatedUsername()));
398 247
399 if (!PrepareForSignin(SIGNIN_TYPE_WITH_CREDENTIALS, username, password)) 248 if (!PrepareForSignin(SIGNIN_TYPE_WITH_CREDENTIALS, username, password))
400 return; 249 return;
401 250
402 if (password.empty()) { 251 if (password.empty()) {
403 // Chrome must verify the GAIA cookies first if auto sign-in is triggered 252 // Chrome must verify the GAIA cookies first if auto sign-in is triggered
404 // with no password provided. This is to protect Chrome against forged 253 // with no password provided. This is to protect Chrome against forged
405 // GAIA cookies from a super-domain. 254 // GAIA cookies from a super-domain.
406 VerifyGaiaCookiesBeforeSignIn(session_index); 255 VerifyGaiaCookiesBeforeSignIn(session_index);
407 } else { 256 } else {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 if (success) { 300 if (success) {
452 client_login_->StartCookieForOAuthLoginTokenExchange(session_index); 301 client_login_->StartCookieForOAuthLoginTokenExchange(session_index);
453 } else { 302 } else {
454 HandleAuthError(GoogleServiceAuthError( 303 HandleAuthError(GoogleServiceAuthError(
455 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS), true); 304 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS), true);
456 } 305 }
457 } 306 }
458 307
459 void SigninManager::StartSignInWithOAuth(const std::string& username, 308 void SigninManager::StartSignInWithOAuth(const std::string& username,
460 const std::string& password) { 309 const std::string& password) {
461 DCHECK(authenticated_username_.empty()); 310 DCHECK(GetAuthenticatedUsername().empty());
462 311
463 if (!PrepareForSignin(SIGNIN_TYPE_CLIENT_OAUTH, username, password)) 312 if (!PrepareForSignin(SIGNIN_TYPE_CLIENT_OAUTH, username, password))
464 return; 313 return;
465 314
466 std::vector<std::string> scopes; 315 std::vector<std::string> scopes;
467 scopes.push_back(GaiaUrls::GetInstance()->oauth1_login_scope()); 316 scopes.push_back(GaiaUrls::GetInstance()->oauth1_login_scope());
468 const std::string& locale = g_browser_process->GetApplicationLocale(); 317 const std::string& locale = g_browser_process->GetApplicationLocale();
469 318
470 client_login_->StartClientOAuth( 319 client_login_->StartClientOAuth(
471 username, password, scopes, std::string(), locale); 320 username, password, scopes, std::string(), locale);
472 321
473 // Register for token availability. The signin manager will pre-login the 322 // Register for token availability. The signin manager will pre-login the
474 // user when the GAIA service token is ready for use. Only do this if we 323 // user when the GAIA service token is ready for use.
475 // are not running in ChomiumOS, since it handles pre-login itself, and if
476 // cookies are not disabled for Google accounts.
477 #if !defined(OS_CHROMEOS)
478 if (AreSigninCookiesAllowed(profile_)) { 324 if (AreSigninCookiesAllowed(profile_)) {
479 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 325 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
480 registrar_.Add(this, 326 registrar_.Add(this,
481 chrome::NOTIFICATION_TOKEN_AVAILABLE, 327 chrome::NOTIFICATION_TOKEN_AVAILABLE,
482 content::Source<TokenService>(token_service)); 328 content::Source<TokenService>(token_service));
483 } 329 }
484 #endif
485 } 330 }
486 331
487 void SigninManager::ProvideOAuthChallengeResponse( 332 void SigninManager::ProvideOAuthChallengeResponse(
488 GoogleServiceAuthError::State type, 333 GoogleServiceAuthError::State type,
489 const std::string& token, 334 const std::string& token,
490 const std::string& solution) { 335 const std::string& solution) {
491 DCHECK(!possibly_invalid_username_.empty() && !password_.empty()); 336 DCHECK(!possibly_invalid_username_.empty() && !password_.empty());
492 DCHECK(type_ == SIGNIN_TYPE_CLIENT_OAUTH); 337 DCHECK(type_ == SIGNIN_TYPE_CLIENT_OAUTH);
493 338
494 client_login_.reset(new GaiaAuthFetcher(this, 339 client_login_.reset(new GaiaAuthFetcher(this,
495 GaiaConstants::kChromeSource, 340 GaiaConstants::kChromeSource,
496 profile_->GetRequestContext())); 341 profile_->GetRequestContext()));
497 client_login_->StartClientOAuthChallengeResponse(type, token, solution); 342 client_login_->StartClientOAuthChallengeResponse(type, token, solution);
498 } 343 }
499 344
500 void SigninManager::ClearTransientSigninData() { 345 void SigninManager::ClearTransientSigninData() {
501 DCHECK(IsInitialized()); 346 DCHECK(IsInitialized());
502 347
503 CleanupNotificationRegistration(); 348 CleanupNotificationRegistration();
504 client_login_.reset(); 349 client_login_.reset();
505 #if defined(ENABLE_CONFIGURATION_POLICY) && !defined(OS_CHROMEOS) 350 #if defined(ENABLE_CONFIGURATION_POLICY)
506 policy_client_.reset(); 351 policy_client_.reset();
507 #endif 352 #endif
508 last_result_ = ClientLoginResult(); 353 last_result_ = ClientLoginResult();
509 possibly_invalid_username_.clear(); 354 possibly_invalid_username_.clear();
510 password_.clear(); 355 password_.clear();
511 had_two_factor_error_ = false; 356 had_two_factor_error_ = false;
512 type_ = SIGNIN_TYPE_NONE; 357 type_ = SIGNIN_TYPE_NONE;
513 temp_oauth_login_tokens_ = ClientOAuthResult(); 358 temp_oauth_login_tokens_ = ClientOAuthResult();
514 } 359 }
515 360
516 void SigninManager::HandleAuthError(const GoogleServiceAuthError& error, 361 void SigninManager::HandleAuthError(const GoogleServiceAuthError& error,
517 bool clear_transient_data) { 362 bool clear_transient_data) {
518 // In some cases, the user should not be signed out. For example, the failure 363 // In some cases, the user should not be signed out. For example, the failure
519 // may be due to a captcha or OTP challenge. In these cases, the transient 364 // may be due to a captcha or OTP challenge. In these cases, the transient
520 // data must be kept to properly handle the follow up. This routine clears 365 // data must be kept to properly handle the follow up. This routine clears
521 // the data before sending out the notification so the SigninManager is no 366 // the data before sending out the notification so the SigninManager is no
522 // longer in the AuthInProgress state when the notification goes out. 367 // longer in the AuthInProgress state when the notification goes out.
523 if (clear_transient_data) 368 if (clear_transient_data)
524 ClearTransientSigninData(); 369 ClearTransientSigninData();
525 370
526 content::NotificationService::current()->Notify( 371 content::NotificationService::current()->Notify(
527 chrome::NOTIFICATION_GOOGLE_SIGNIN_FAILED, 372 chrome::NOTIFICATION_GOOGLE_SIGNIN_FAILED,
528 content::Source<Profile>(profile_), 373 content::Source<Profile>(profile_),
529 content::Details<const GoogleServiceAuthError>(&error)); 374 content::Details<const GoogleServiceAuthError>(&error));
530 } 375 }
531 376
532 void SigninManager::SignOut() { 377 void SigninManager::SignOut() {
533 DCHECK(IsInitialized()); 378 DCHECK(IsInitialized());
534 379
535 if (authenticated_username_.empty()) { 380 if (GetAuthenticatedUsername().empty()) {
536 if (AuthInProgress()) { 381 if (AuthInProgress()) {
537 // If the user is in the process of signing in, then treat a call to 382 // If the user is in the process of signing in, then treat a call to
538 // SignOut as a cancellation request. 383 // SignOut as a cancellation request.
539 GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED); 384 GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED);
540 HandleAuthError(error, true); 385 HandleAuthError(error, true);
541 } else { 386 } else {
542 // Clean up our transient data and exit if we aren't signed in. 387 // Clean up our transient data and exit if we aren't signed in.
543 // This avoids a perf regression from clearing out the TokenDB if 388 // This avoids a perf regression from clearing out the TokenDB if
544 // SignOut() is invoked on startup to clean up any incomplete previous 389 // SignOut() is invoked on startup to clean up any incomplete previous
545 // signin attempts. 390 // signin attempts.
546 ClearTransientSigninData(); 391 ClearTransientSigninData();
547 } 392 }
548 return; 393 return;
549 } 394 }
550 395
551 if (prohibit_signout_) { 396 if (prohibit_signout_) {
552 DVLOG(1) << "Ignoring attempt to sign out while signout is prohibited"; 397 DVLOG(1) << "Ignoring attempt to sign out while signout is prohibited";
553 return; 398 return;
554 } 399 }
555 DCHECK(!authenticated_username_.empty());
556 GoogleServiceSignoutDetails details(authenticated_username_);
557 400
558 ClearTransientSigninData(); 401 ClearTransientSigninData();
559 authenticated_username_.clear();
560 profile_->GetPrefs()->ClearPref(prefs::kGoogleServicesUsername);
561
562 // Erase (now) stale information from AboutSigninInternals.
563 NotifyDiagnosticsObservers(USERNAME, std::string());
564 NotifyDiagnosticsObservers(LSID, std::string());
565 NotifyDiagnosticsObservers(signin_internals_util::SID, std::string());
566
567 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
568 content::NotificationService::current()->Notify(
569 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
570 content::Source<Profile>(profile_),
571 content::Details<const GoogleServiceSignoutDetails>(&details));
572 RevokeOAuthLoginToken(); 402 RevokeOAuthLoginToken();
573 token_service->ResetCredentialsInMemory(); 403 SigninManagerBase::SignOut();
574 token_service->EraseTokensFromDB();
575 } 404 }
576 405
577 void SigninManager::RevokeOAuthLoginToken() { 406 void SigninManager::RevokeOAuthLoginToken() {
578 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 407 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
579 if (token_service->HasOAuthLoginToken()) { 408 if (token_service->HasOAuthLoginToken()) {
580 revoke_token_fetcher_.reset( 409 revoke_token_fetcher_.reset(
581 new GaiaAuthFetcher(this, 410 new GaiaAuthFetcher(this,
582 GaiaConstants::kChromeSource, 411 GaiaConstants::kChromeSource,
583 profile_->GetRequestContext())); 412 profile_->GetRequestContext()));
584 revoke_token_fetcher_->StartRevokeOAuth2Token( 413 revoke_token_fetcher_->StartRevokeOAuth2Token(
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 // expected, return an error. 525 // expected, return an error.
697 if (type_ == SIGNIN_TYPE_WITH_CREDENTIALS && 526 if (type_ == SIGNIN_TYPE_WITH_CREDENTIALS &&
698 !gaia::AreEmailsSame(display_email_iter->second, 527 !gaia::AreEmailsSame(display_email_iter->second,
699 possibly_invalid_username_)) { 528 possibly_invalid_username_)) {
700 OnGetUserInfoKeyNotFound(kGetInfoDisplayEmailKey); 529 OnGetUserInfoKeyNotFound(kGetInfoDisplayEmailKey);
701 return; 530 return;
702 } 531 }
703 532
704 possibly_invalid_username_ = email_iter->second; 533 possibly_invalid_username_ = email_iter->second;
705 534
706 #if defined(ENABLE_CONFIGURATION_POLICY) && !defined(OS_CHROMEOS) 535 #if defined(ENABLE_CONFIGURATION_POLICY)
707 // TODO(atwilson): Move this code out to OneClickSignin instead of having 536 // TODO(atwilson): Move this code out to OneClickSignin instead of having
708 // it embedded in SigninManager - we don't want UI logic in SigninManager. 537 // it embedded in SigninManager - we don't want UI logic in SigninManager.
709 // If this is a new signin (authenticated_username_ is not set) and we have 538 // If this is a new signin (authenticated_username_ is not set) and we have
710 // an OAuth token, try loading policy for this user now, before any signed in 539 // an OAuth token, try loading policy for this user now, before any signed in
711 // services are initialized. If there's no oauth token (the user is using the 540 // services are initialized. If there's no oauth token (the user is using the
712 // old ClientLogin flow) then policy will get loaded once the TokenService 541 // old ClientLogin flow) then policy will get loaded once the TokenService
713 // finishes initializing (not ideal, but it's a reasonable fallback). 542 // finishes initializing (not ideal, but it's a reasonable fallback).
714 if (authenticated_username_.empty() && 543 if (GetAuthenticatedUsername().empty() &&
715 !temp_oauth_login_tokens_.refresh_token.empty()) { 544 !temp_oauth_login_tokens_.refresh_token.empty()) {
716 policy::UserPolicySigninService* policy_service = 545 policy::UserPolicySigninService* policy_service =
717 policy::UserPolicySigninServiceFactory::GetForProfile(profile_); 546 policy::UserPolicySigninServiceFactory::GetForProfile(profile_);
718 policy_service->RegisterPolicyClient( 547 policy_service->RegisterPolicyClient(
719 possibly_invalid_username_, 548 possibly_invalid_username_,
720 temp_oauth_login_tokens_.refresh_token, 549 temp_oauth_login_tokens_.refresh_token,
721 base::Bind(&SigninManager::OnRegisteredForPolicy, 550 base::Bind(&SigninManager::OnRegisteredForPolicy,
722 weak_pointer_factory_.GetWeakPtr())); 551 weak_pointer_factory_.GetWeakPtr()));
723 return; 552 return;
724 } 553 }
725 #endif 554 #endif
726 555
727 // Not waiting for policy load - just complete signin directly. 556 // Not waiting for policy load - just complete signin directly.
728 CompleteSigninAfterPolicyLoad(); 557 CompleteSigninAfterPolicyLoad();
729 } 558 }
730 559
731 #if defined(ENABLE_CONFIGURATION_POLICY) && !defined(OS_CHROMEOS) 560 #if defined(ENABLE_CONFIGURATION_POLICY)
732 void SigninManager::OnRegisteredForPolicy( 561 void SigninManager::OnRegisteredForPolicy(
733 scoped_ptr<policy::CloudPolicyClient> client) { 562 scoped_ptr<policy::CloudPolicyClient> client) {
734 // If there's no token for the user (no policy) just finish signing in. 563 // If there's no token for the user (no policy) just finish signing in.
735 if (!client.get()) { 564 if (!client.get()) {
736 DVLOG(1) << "Policy registration failed"; 565 DVLOG(1) << "Policy registration failed";
737 CompleteSigninAfterPolicyLoad(); 566 CompleteSigninAfterPolicyLoad();
738 return; 567 return;
739 } 568 }
740 569
741 // Stash away a copy of our CloudPolicyClient (should not already have one). 570 // Stash away a copy of our CloudPolicyClient (should not already have one).
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 SignOut(); 656 SignOut();
828 } 657 }
829 } 658 }
830 #endif 659 #endif
831 660
832 void SigninManager::CompleteSigninAfterPolicyLoad() { 661 void SigninManager::CompleteSigninAfterPolicyLoad() {
833 DCHECK(!possibly_invalid_username_.empty()); 662 DCHECK(!possibly_invalid_username_.empty());
834 SetAuthenticatedUsername(possibly_invalid_username_); 663 SetAuthenticatedUsername(possibly_invalid_username_);
835 possibly_invalid_username_.clear(); 664 possibly_invalid_username_.clear();
836 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername, 665 profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
837 authenticated_username_); 666 GetAuthenticatedUsername());
838 667
839 GoogleServiceSigninSuccessDetails details(authenticated_username_, 668 GoogleServiceSigninSuccessDetails details(GetAuthenticatedUsername(),
840 password_); 669 password_);
841 content::NotificationService::current()->Notify( 670 content::NotificationService::current()->Notify(
842 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, 671 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
843 content::Source<Profile>(profile_), 672 content::Source<Profile>(profile_),
844 content::Details<const GoogleServiceSigninSuccessDetails>(&details)); 673 content::Details<const GoogleServiceSigninSuccessDetails>(&details));
845 674
846 password_.clear(); // Don't need it anymore. 675 password_.clear(); // Don't need it anymore.
847 DisableOneClickSignIn(profile_); // Don't ever offer again. 676 DisableOneClickSignIn(profile_); // Don't ever offer again.
848 677
849 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 678 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
(...skipping 30 matching lines...) Expand all
880 709
881 void SigninManager::OnUbertokenFailure(const GoogleServiceAuthError& error) { 710 void SigninManager::OnUbertokenFailure(const GoogleServiceAuthError& error) {
882 LOG(WARNING) << " Unable to login the user to the web: " << error.ToString(); 711 LOG(WARNING) << " Unable to login the user to the web: " << error.ToString();
883 ubertoken_fetcher_.reset(); 712 ubertoken_fetcher_.reset();
884 } 713 }
885 714
886 void SigninManager::Observe(int type, 715 void SigninManager::Observe(int type,
887 const content::NotificationSource& source, 716 const content::NotificationSource& source,
888 const content::NotificationDetails& details) { 717 const content::NotificationDetails& details) {
889 switch (type) { 718 switch (type) {
890 #if !defined(OS_CHROMEOS)
891 case chrome::NOTIFICATION_TOKEN_AVAILABLE: { 719 case chrome::NOTIFICATION_TOKEN_AVAILABLE: {
892 TokenService::TokenAvailableDetails* tok_details = 720 TokenService::TokenAvailableDetails* tok_details =
893 content::Details<TokenService::TokenAvailableDetails>( 721 content::Details<TokenService::TokenAvailableDetails>(
894 details).ptr(); 722 details).ptr();
895 723
896 // If a GAIA service token has become available, use it to pre-login the 724 // If a GAIA service token has become available, use it to pre-login the
897 // user to other services that depend on GAIA credentials. 725 // user to other services that depend on GAIA credentials.
898 if (tok_details->service() == 726 if (tok_details->service() ==
899 GaiaConstants::kGaiaOAuth2LoginRefreshToken) { 727 GaiaConstants::kGaiaOAuth2LoginRefreshToken) {
900 ubertoken_fetcher_.reset(new UbertokenFetcher(profile_, this)); 728 ubertoken_fetcher_.reset(new UbertokenFetcher(profile_, this));
(...skipping 11 matching lines...) Expand all
912 // if this was from the current signin process. 740 // if this was from the current signin process.
913 registrar_.Remove(this, 741 registrar_.Remove(this,
914 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 742 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
915 source); 743 source);
916 if (signin_process_id_ == 744 if (signin_process_id_ ==
917 content::Source<content::RenderProcessHost>(source)->GetID()) { 745 content::Source<content::RenderProcessHost>(source)->GetID()) {
918 signin_process_id_ = kInvalidProcessId; 746 signin_process_id_ = kInvalidProcessId;
919 } 747 }
920 break; 748 break;
921 } 749 }
922 #endif
923 default: 750 default:
924 NOTREACHED(); 751 NOTREACHED();
925 } 752 }
926 } 753 }
927 754
928 void SigninManager::Shutdown() {
929 if (signin_global_error_.get()) {
930 GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError(
931 signin_global_error_.get());
932 signin_global_error_.reset();
933 }
934 }
935
936 void SigninManager::ProhibitSignout(bool prohibit_signout) { 755 void SigninManager::ProhibitSignout(bool prohibit_signout) {
937 prohibit_signout_ = prohibit_signout; 756 prohibit_signout_ = prohibit_signout;
938 } 757 }
939 758
940 bool SigninManager::IsSignoutProhibited() const { 759 bool SigninManager::IsSignoutProhibited() const {
941 return prohibit_signout_; 760 return prohibit_signout_;
942 } 761 }
943
944 void SigninManager::OnGoogleServicesUsernamePatternChanged() {
945 if (!authenticated_username_.empty() &&
946 !IsAllowedUsername(authenticated_username_)) {
947 // Signed in user is invalid according to the current policy so sign
948 // the user out.
949 SignOut();
950 }
951 }
952
953 void SigninManager::OnSigninAllowedPrefChanged() {
954 if (!IsSigninAllowed())
955 SignOut();
956 }
957
958 void SigninManager::AddSigninDiagnosticsObserver(
959 SigninDiagnosticsObserver* observer) {
960 signin_diagnostics_observers_.AddObserver(observer);
961 }
962
963 void SigninManager::RemoveSigninDiagnosticsObserver(
964 SigninDiagnosticsObserver* observer) {
965 signin_diagnostics_observers_.RemoveObserver(observer);
966 }
967
968 void SigninManager::NotifyDiagnosticsObservers(
969 const UntimedSigninStatusField& field,
970 const std::string& value) {
971 FOR_EACH_OBSERVER(SigninDiagnosticsObserver,
972 signin_diagnostics_observers_,
973 NotifySigninValueChanged(field, value));
974 }
975
976 void SigninManager::NotifyDiagnosticsObservers(
977 const TimedSigninStatusField& field,
978 const std::string& value) {
979 FOR_EACH_OBSERVER(SigninDiagnosticsObserver,
980 signin_diagnostics_observers_,
981 NotifySigninValueChanged(field, value));
982 }
OLDNEW
« no previous file with comments | « chrome/browser/signin/signin_manager.h ('k') | chrome/browser/signin/signin_manager_base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698