Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 354 return; | 354 return; |
| 355 } | 355 } |
| 356 | 356 |
| 357 if (prohibit_signout_) { | 357 if (prohibit_signout_) { |
| 358 DVLOG(1) << "Ignoring attempt to sign out while signout is prohibited"; | 358 DVLOG(1) << "Ignoring attempt to sign out while signout is prohibited"; |
| 359 return; | 359 return; |
| 360 } | 360 } |
| 361 | 361 |
| 362 ClearTransientSigninData(); | 362 ClearTransientSigninData(); |
| 363 RevokeOAuthLoginToken(); | 363 RevokeOAuthLoginToken(); |
| 364 SigninManagerBase::SignOut(); | 364 |
| 365 GoogleServiceSignoutDetails details(GetAuthenticatedUsername()); | |
| 366 clear_authenticated_username(); | |
| 367 profile_->GetPrefs()->ClearPref(prefs::kGoogleServicesUsername); | |
| 368 | |
| 369 // Erase (now) stale information from AboutSigninInternals. | |
| 370 NotifyDiagnosticsObservers(USERNAME, ""); | |
| 371 NotifyDiagnosticsObservers(LSID, ""); | |
| 372 NotifyDiagnosticsObservers( | |
| 373 signin_internals_util::SID, ""); | |
| 374 | |
| 375 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); | |
|
Andrew T Wilson (Slow)
2013/05/06 09:06:00
Maybe move this down to line 380 - no reason to gr
tim (not reviewing)
2013/05/06 17:28:57
Done.
| |
| 376 content::NotificationService::current()->Notify( | |
| 377 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, | |
| 378 content::Source<Profile>(profile_), | |
| 379 content::Details<const GoogleServiceSignoutDetails>(&details)); | |
| 380 token_service->ResetCredentialsInMemory(); | |
| 381 token_service->EraseTokensFromDB(); | |
| 382 } | |
| 383 | |
| 384 void SigninManager::Initialize(Profile* profile) { | |
| 385 SigninManagerBase::Initialize(profile); | |
| 386 | |
| 387 // local_state can be null during unit tests. | |
| 388 PrefService* local_state = g_browser_process->local_state(); | |
| 389 if (local_state) { | |
| 390 local_state_pref_registrar_.Init(local_state); | |
| 391 local_state_pref_registrar_.Add( | |
| 392 prefs::kGoogleServicesUsernamePattern, | |
| 393 base::Bind(&SigninManager::OnGoogleServicesUsernamePatternChanged, | |
| 394 weak_pointer_factory_.GetWeakPtr())); | |
| 395 } | |
| 396 signin_allowed_.Init(prefs::kSigninAllowed, profile_->GetPrefs(), | |
| 397 base::Bind(&SigninManager::OnSigninAllowedPrefChanged, | |
| 398 base::Unretained(this))); | |
| 399 | |
| 400 std::string user = profile_->GetPrefs()->GetString( | |
| 401 prefs::kGoogleServicesUsername); | |
| 402 if ((!user.empty() && !IsAllowedUsername(user)) || !IsSigninAllowed()) { | |
| 403 // User is signed in, but the username is invalid - the administrator must | |
| 404 // have changed the policy since the last signin, so sign out the user. | |
| 405 SignOut(); | |
| 406 } | |
| 407 } | |
| 408 | |
| 409 void SigninManager::OnGoogleServicesUsernamePatternChanged() { | |
| 410 if (!GetAuthenticatedUsername().empty() && | |
| 411 !IsAllowedUsername(GetAuthenticatedUsername())) { | |
| 412 // Signed in user is invalid according to the current policy so sign | |
| 413 // the user out. | |
| 414 SignOut(); | |
| 415 } | |
| 416 } | |
| 417 | |
| 418 bool SigninManager::IsSigninAllowed() const { | |
| 419 return signin_allowed_.GetValue(); | |
| 420 } | |
| 421 | |
| 422 // static | |
| 423 bool SigninManager::IsSigninAllowedOnIOThread(ProfileIOData* io_data) { | |
| 424 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
| 425 return io_data->signin_allowed()->GetValue(); | |
| 426 } | |
| 427 | |
| 428 void SigninManager::OnSigninAllowedPrefChanged() { | |
| 429 if (!IsSigninAllowed()) | |
| 430 SignOut(); | |
| 431 } | |
| 432 | |
| 433 // static | |
| 434 bool SigninManager::IsUsernameAllowedByPolicy(const std::string& username, | |
| 435 const std::string& policy) { | |
| 436 if (policy.empty()) | |
| 437 return true; | |
| 438 | |
| 439 // Patterns like "*@foo.com" are not accepted by our regex engine (since they | |
| 440 // are not valid regular expressions - they should instead be ".*@foo.com"). | |
| 441 // For convenience, detect these patterns and insert a "." character at the | |
| 442 // front. | |
| 443 string16 pattern = UTF8ToUTF16(policy); | |
| 444 if (pattern[0] == L'*') | |
| 445 pattern.insert(pattern.begin(), L'.'); | |
| 446 | |
| 447 // See if the username matches the policy-provided pattern. | |
| 448 UErrorCode status = U_ZERO_ERROR; | |
| 449 const icu::UnicodeString icu_pattern(pattern.data(), pattern.length()); | |
| 450 icu::RegexMatcher matcher(icu_pattern, UREGEX_CASE_INSENSITIVE, status); | |
| 451 if (!U_SUCCESS(status)) { | |
| 452 LOG(ERROR) << "Invalid login regex: " << pattern << ", status: " << status; | |
| 453 // If an invalid pattern is provided, then prohibit *all* logins (better to | |
| 454 // break signin than to quietly allow users to sign in). | |
| 455 return false; | |
| 456 } | |
| 457 string16 username16 = UTF8ToUTF16(username); | |
| 458 icu::UnicodeString icu_input(username16.data(), username16.length()); | |
| 459 matcher.reset(icu_input); | |
| 460 status = U_ZERO_ERROR; | |
| 461 UBool match = matcher.matches(status); | |
| 462 DCHECK(U_SUCCESS(status)); | |
| 463 return !!match; // !! == convert from UBool to bool. | |
| 464 } | |
| 465 | |
| 466 bool SigninManager::IsAllowedUsername(const std::string& username) const { | |
| 467 PrefService* local_state = g_browser_process->local_state(); | |
| 468 if (!local_state) | |
| 469 return true; // In a unit test with no local state - all names are allowed. | |
| 470 | |
| 471 std::string pattern = local_state->GetString( | |
| 472 prefs::kGoogleServicesUsernamePattern); | |
| 473 return IsUsernameAllowedByPolicy(username, pattern); | |
| 365 } | 474 } |
| 366 | 475 |
| 367 void SigninManager::RevokeOAuthLoginToken() { | 476 void SigninManager::RevokeOAuthLoginToken() { |
| 368 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); | 477 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); |
| 369 if (token_service->HasOAuthLoginToken()) { | 478 if (token_service->HasOAuthLoginToken()) { |
| 370 revoke_token_fetcher_.reset( | 479 revoke_token_fetcher_.reset( |
| 371 new GaiaAuthFetcher(this, | 480 new GaiaAuthFetcher(this, |
| 372 GaiaConstants::kChromeSource, | 481 GaiaConstants::kChromeSource, |
| 373 profile_->GetRequestContext())); | 482 profile_->GetRequestContext())); |
| 374 revoke_token_fetcher_->StartRevokeOAuth2Token( | 483 revoke_token_fetcher_->StartRevokeOAuth2Token( |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 705 } | 814 } |
| 706 } | 815 } |
| 707 | 816 |
| 708 void SigninManager::ProhibitSignout(bool prohibit_signout) { | 817 void SigninManager::ProhibitSignout(bool prohibit_signout) { |
| 709 prohibit_signout_ = prohibit_signout; | 818 prohibit_signout_ = prohibit_signout; |
| 710 } | 819 } |
| 711 | 820 |
| 712 bool SigninManager::IsSignoutProhibited() const { | 821 bool SigninManager::IsSignoutProhibited() const { |
| 713 return prohibit_signout_; | 822 return prohibit_signout_; |
| 714 } | 823 } |
| OLD | NEW |