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" |
11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
12 #include "base/prefs/pref_service.h" | 12 #include "base/prefs/pref_service.h" |
13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
14 #include "base/strings/string_split.h" | 14 #include "base/strings/string_split.h" |
15 #include "base/time.h" | 15 #include "base/time.h" |
| 16 #include "base/utf_string_conversions.h" |
16 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
| 18 #include "chrome/browser/profiles/profile_io_data.h" |
17 #include "chrome/browser/signin/about_signin_internals.h" | 19 #include "chrome/browser/signin/about_signin_internals.h" |
18 #include "chrome/browser/signin/about_signin_internals_factory.h" | 20 #include "chrome/browser/signin/about_signin_internals_factory.h" |
19 #include "chrome/browser/signin/signin_global_error.h" | 21 #include "chrome/browser/signin/signin_global_error.h" |
20 #include "chrome/browser/signin/signin_internals_util.h" | 22 #include "chrome/browser/signin/signin_internals_util.h" |
21 #include "chrome/browser/signin/signin_manager_cookie_helper.h" | 23 #include "chrome/browser/signin/signin_manager_cookie_helper.h" |
22 #include "chrome/browser/signin/signin_manager_delegate.h" | 24 #include "chrome/browser/signin/signin_manager_delegate.h" |
23 #include "chrome/browser/signin/signin_manager_factory.h" | 25 #include "chrome/browser/signin/signin_manager_factory.h" |
24 #include "chrome/browser/signin/token_service.h" | 26 #include "chrome/browser/signin/token_service.h" |
25 #include "chrome/browser/signin/token_service_factory.h" | 27 #include "chrome/browser/signin/token_service_factory.h" |
26 #include "chrome/browser/ui/global_error/global_error_service.h" | 28 #include "chrome/browser/ui/global_error/global_error_service.h" |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 return; | 355 return; |
354 } | 356 } |
355 | 357 |
356 if (prohibit_signout_) { | 358 if (prohibit_signout_) { |
357 DVLOG(1) << "Ignoring attempt to sign out while signout is prohibited"; | 359 DVLOG(1) << "Ignoring attempt to sign out while signout is prohibited"; |
358 return; | 360 return; |
359 } | 361 } |
360 | 362 |
361 ClearTransientSigninData(); | 363 ClearTransientSigninData(); |
362 RevokeOAuthLoginToken(); | 364 RevokeOAuthLoginToken(); |
363 SigninManagerBase::SignOut(); | 365 |
| 366 GoogleServiceSignoutDetails details(GetAuthenticatedUsername()); |
| 367 clear_authenticated_username(); |
| 368 profile_->GetPrefs()->ClearPref(prefs::kGoogleServicesUsername); |
| 369 |
| 370 // Erase (now) stale information from AboutSigninInternals. |
| 371 NotifyDiagnosticsObservers(USERNAME, ""); |
| 372 NotifyDiagnosticsObservers(LSID, ""); |
| 373 NotifyDiagnosticsObservers( |
| 374 signin_internals_util::SID, ""); |
| 375 |
| 376 content::NotificationService::current()->Notify( |
| 377 chrome::NOTIFICATION_GOOGLE_SIGNED_OUT, |
| 378 content::Source<Profile>(profile_), |
| 379 content::Details<const GoogleServiceSignoutDetails>(&details)); |
| 380 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); |
| 381 token_service->ResetCredentialsInMemory(); |
| 382 token_service->EraseTokensFromDB(); |
| 383 } |
| 384 |
| 385 void SigninManager::Initialize(Profile* profile) { |
| 386 SigninManagerBase::Initialize(profile); |
| 387 |
| 388 // local_state can be null during unit tests. |
| 389 PrefService* local_state = g_browser_process->local_state(); |
| 390 if (local_state) { |
| 391 local_state_pref_registrar_.Init(local_state); |
| 392 local_state_pref_registrar_.Add( |
| 393 prefs::kGoogleServicesUsernamePattern, |
| 394 base::Bind(&SigninManager::OnGoogleServicesUsernamePatternChanged, |
| 395 weak_pointer_factory_.GetWeakPtr())); |
| 396 } |
| 397 signin_allowed_.Init(prefs::kSigninAllowed, profile_->GetPrefs(), |
| 398 base::Bind(&SigninManager::OnSigninAllowedPrefChanged, |
| 399 base::Unretained(this))); |
| 400 |
| 401 std::string user = profile_->GetPrefs()->GetString( |
| 402 prefs::kGoogleServicesUsername); |
| 403 if ((!user.empty() && !IsAllowedUsername(user)) || !IsSigninAllowed()) { |
| 404 // User is signed in, but the username is invalid - the administrator must |
| 405 // have changed the policy since the last signin, so sign out the user. |
| 406 SignOut(); |
| 407 } |
| 408 } |
| 409 |
| 410 void SigninManager::OnGoogleServicesUsernamePatternChanged() { |
| 411 if (!GetAuthenticatedUsername().empty() && |
| 412 !IsAllowedUsername(GetAuthenticatedUsername())) { |
| 413 // Signed in user is invalid according to the current policy so sign |
| 414 // the user out. |
| 415 SignOut(); |
| 416 } |
| 417 } |
| 418 |
| 419 bool SigninManager::IsSigninAllowed() const { |
| 420 return signin_allowed_.GetValue(); |
| 421 } |
| 422 |
| 423 // static |
| 424 bool SigninManager::IsSigninAllowedOnIOThread(ProfileIOData* io_data) { |
| 425 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 426 return io_data->signin_allowed()->GetValue(); |
| 427 } |
| 428 |
| 429 void SigninManager::OnSigninAllowedPrefChanged() { |
| 430 if (!IsSigninAllowed()) |
| 431 SignOut(); |
| 432 } |
| 433 |
| 434 // static |
| 435 bool SigninManager::IsUsernameAllowedByPolicy(const std::string& username, |
| 436 const std::string& policy) { |
| 437 if (policy.empty()) |
| 438 return true; |
| 439 |
| 440 // Patterns like "*@foo.com" are not accepted by our regex engine (since they |
| 441 // are not valid regular expressions - they should instead be ".*@foo.com"). |
| 442 // For convenience, detect these patterns and insert a "." character at the |
| 443 // front. |
| 444 string16 pattern = UTF8ToUTF16(policy); |
| 445 if (pattern[0] == L'*') |
| 446 pattern.insert(pattern.begin(), L'.'); |
| 447 |
| 448 // See if the username matches the policy-provided pattern. |
| 449 UErrorCode status = U_ZERO_ERROR; |
| 450 const icu::UnicodeString icu_pattern(pattern.data(), pattern.length()); |
| 451 icu::RegexMatcher matcher(icu_pattern, UREGEX_CASE_INSENSITIVE, status); |
| 452 if (!U_SUCCESS(status)) { |
| 453 LOG(ERROR) << "Invalid login regex: " << pattern << ", status: " << status; |
| 454 // If an invalid pattern is provided, then prohibit *all* logins (better to |
| 455 // break signin than to quietly allow users to sign in). |
| 456 return false; |
| 457 } |
| 458 string16 username16 = UTF8ToUTF16(username); |
| 459 icu::UnicodeString icu_input(username16.data(), username16.length()); |
| 460 matcher.reset(icu_input); |
| 461 status = U_ZERO_ERROR; |
| 462 UBool match = matcher.matches(status); |
| 463 DCHECK(U_SUCCESS(status)); |
| 464 return !!match; // !! == convert from UBool to bool. |
| 465 } |
| 466 |
| 467 bool SigninManager::IsAllowedUsername(const std::string& username) const { |
| 468 PrefService* local_state = g_browser_process->local_state(); |
| 469 if (!local_state) |
| 470 return true; // In a unit test with no local state - all names are allowed. |
| 471 |
| 472 std::string pattern = local_state->GetString( |
| 473 prefs::kGoogleServicesUsernamePattern); |
| 474 return IsUsernameAllowedByPolicy(username, pattern); |
364 } | 475 } |
365 | 476 |
366 void SigninManager::RevokeOAuthLoginToken() { | 477 void SigninManager::RevokeOAuthLoginToken() { |
367 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); | 478 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); |
368 if (token_service->HasOAuthLoginToken()) { | 479 if (token_service->HasOAuthLoginToken()) { |
369 revoke_token_fetcher_.reset( | 480 revoke_token_fetcher_.reset( |
370 new GaiaAuthFetcher(this, | 481 new GaiaAuthFetcher(this, |
371 GaiaConstants::kChromeSource, | 482 GaiaConstants::kChromeSource, |
372 profile_->GetRequestContext())); | 483 profile_->GetRequestContext())); |
373 revoke_token_fetcher_->StartRevokeOAuth2Token( | 484 revoke_token_fetcher_->StartRevokeOAuth2Token( |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 } | 699 } |
589 } | 700 } |
590 | 701 |
591 void SigninManager::ProhibitSignout(bool prohibit_signout) { | 702 void SigninManager::ProhibitSignout(bool prohibit_signout) { |
592 prohibit_signout_ = prohibit_signout; | 703 prohibit_signout_ = prohibit_signout; |
593 } | 704 } |
594 | 705 |
595 bool SigninManager::IsSignoutProhibited() const { | 706 bool SigninManager::IsSignoutProhibited() const { |
596 return prohibit_signout_; | 707 return prohibit_signout_; |
597 } | 708 } |
OLD | NEW |