| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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/ui/webui/signin/user_manager_screen_handler.h" | 5 #include "chrome/browser/ui/webui/signin/user_manager_screen_handler.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
| 10 #include "base/profiler/scoped_tracker.h" | 10 #include "base/profiler/scoped_tracker.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 if (avatar_image.Width() <= profiles::kAvatarIconWidth || | 117 if (avatar_image.Width() <= profiles::kAvatarIconWidth || |
| 118 avatar_image.Height() <= profiles::kAvatarIconHeight ) { | 118 avatar_image.Height() <= profiles::kAvatarIconHeight ) { |
| 119 avatar_image = ui::ResourceBundle::GetSharedInstance().GetImageNamed( | 119 avatar_image = ui::ResourceBundle::GetSharedInstance().GetImageNamed( |
| 120 profiles::GetPlaceholderAvatarIconResourceID()); | 120 profiles::GetPlaceholderAvatarIconResourceID()); |
| 121 } | 121 } |
| 122 gfx::Image resized_image = profiles::GetSizedAvatarIcon( | 122 gfx::Image resized_image = profiles::GetSizedAvatarIcon( |
| 123 avatar_image, is_gaia_picture, kAvatarIconSize, kAvatarIconSize); | 123 avatar_image, is_gaia_picture, kAvatarIconSize, kAvatarIconSize); |
| 124 return webui::GetBitmapDataUrl(resized_image.AsBitmap()); | 124 return webui::GetBitmapDataUrl(resized_image.AsBitmap()); |
| 125 } | 125 } |
| 126 | 126 |
| 127 size_t GetIndexOfProfileWithEmail(const ProfileInfoCache& info_cache, | |
| 128 const std::string& email) { | |
| 129 const base::string16& profile_email = base::UTF8ToUTF16(email); | |
| 130 for (size_t i = 0; i < info_cache.GetNumberOfProfiles(); ++i) { | |
| 131 if (info_cache.GetUserNameOfProfileAtIndex(i) == profile_email) | |
| 132 return i; | |
| 133 } | |
| 134 return std::string::npos; | |
| 135 } | |
| 136 | |
| 137 extensions::ScreenlockPrivateEventRouter* GetScreenlockRouter( | 127 extensions::ScreenlockPrivateEventRouter* GetScreenlockRouter( |
| 138 const std::string& email) { | 128 const std::string& email) { |
| 139 const ProfileInfoCache& info_cache = | 129 base::FilePath path = |
| 140 g_browser_process->profile_manager()->GetProfileInfoCache(); | 130 profiles::GetPathOfProfileWithEmail(g_browser_process->profile_manager(), |
| 141 const size_t profile_index = GetIndexOfProfileWithEmail(info_cache, email); | 131 email); |
| 142 Profile* profile = g_browser_process->profile_manager() | 132 Profile* profile = g_browser_process->profile_manager() |
| 143 ->GetProfileByPath(info_cache.GetPathOfProfileAtIndex(profile_index)); | 133 ->GetProfileByPath(path); |
| 144 return extensions::ScreenlockPrivateEventRouter::GetFactoryInstance()->Get( | 134 return extensions::ScreenlockPrivateEventRouter::GetFactoryInstance()->Get( |
| 145 profile); | 135 profile); |
| 146 } | 136 } |
| 147 | 137 |
| 148 bool IsGuestModeEnabled() { | 138 bool IsGuestModeEnabled() { |
| 149 PrefService* service = g_browser_process->local_state(); | 139 PrefService* service = g_browser_process->local_state(); |
| 150 DCHECK(service); | 140 DCHECK(service); |
| 151 return service->GetBoolean(prefs::kBrowserGuestModeEnabled); | 141 return service->GetBoolean(prefs::kBrowserGuestModeEnabled); |
| 152 } | 142 } |
| 153 | 143 |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 return proximity_auth::ScreenlockBridge::LockHandler::OFFLINE_PASSWORD; | 349 return proximity_auth::ScreenlockBridge::LockHandler::OFFLINE_PASSWORD; |
| 360 return it->second; | 350 return it->second; |
| 361 } | 351 } |
| 362 | 352 |
| 363 proximity_auth::ScreenlockBridge::LockHandler::ScreenType | 353 proximity_auth::ScreenlockBridge::LockHandler::ScreenType |
| 364 UserManagerScreenHandler::GetScreenType() const { | 354 UserManagerScreenHandler::GetScreenType() const { |
| 365 return proximity_auth::ScreenlockBridge::LockHandler::LOCK_SCREEN; | 355 return proximity_auth::ScreenlockBridge::LockHandler::LOCK_SCREEN; |
| 366 } | 356 } |
| 367 | 357 |
| 368 void UserManagerScreenHandler::Unlock(const std::string& user_email) { | 358 void UserManagerScreenHandler::Unlock(const std::string& user_email) { |
| 369 const ProfileInfoCache& info_cache = | 359 base::FilePath path = |
| 370 g_browser_process->profile_manager()->GetProfileInfoCache(); | 360 profiles::GetPathOfProfileWithEmail(g_browser_process->profile_manager(), |
| 371 const size_t profile_index = | 361 user_email); |
| 372 GetIndexOfProfileWithEmail(info_cache, user_email); | 362 if (!path.empty()) { |
| 373 DCHECK_LT(profile_index, info_cache.GetNumberOfProfiles()); | 363 authenticating_profile_path_ = path; |
| 374 | 364 ReportAuthenticationResult(true, ProfileMetrics::AUTH_LOCAL); |
| 375 authenticating_profile_index_ = profile_index; | 365 } |
| 376 ReportAuthenticationResult(true, ProfileMetrics::AUTH_LOCAL); | |
| 377 } | 366 } |
| 378 | 367 |
| 379 void UserManagerScreenHandler::AttemptEasySignin( | 368 void UserManagerScreenHandler::AttemptEasySignin( |
| 380 const std::string& user_email, | 369 const std::string& user_email, |
| 381 const std::string& secret, | 370 const std::string& secret, |
| 382 const std::string& key_label) { | 371 const std::string& key_label) { |
| 383 NOTREACHED(); | 372 NOTREACHED(); |
| 384 } | 373 } |
| 385 | 374 |
| 386 void UserManagerScreenHandler::HandleInitialize(const base::ListValue* args) { | 375 void UserManagerScreenHandler::HandleInitialize(const base::ListValue* args) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 413 void UserManagerScreenHandler::HandleAuthenticatedLaunchUser( | 402 void UserManagerScreenHandler::HandleAuthenticatedLaunchUser( |
| 414 const base::ListValue* args) { | 403 const base::ListValue* args) { |
| 415 const base::Value* profile_path_value; | 404 const base::Value* profile_path_value; |
| 416 if (!args->Get(0, &profile_path_value)) | 405 if (!args->Get(0, &profile_path_value)) |
| 417 return; | 406 return; |
| 418 | 407 |
| 419 base::FilePath profile_path; | 408 base::FilePath profile_path; |
| 420 if (!base::GetValueAsFilePath(*profile_path_value, &profile_path)) | 409 if (!base::GetValueAsFilePath(*profile_path_value, &profile_path)) |
| 421 return; | 410 return; |
| 422 | 411 |
| 412 ProfileInfoCache& info_cache = |
| 413 g_browser_process->profile_manager()->GetProfileInfoCache(); |
| 414 |
| 415 ProfileAttributesEntry* entry; |
| 416 if (!info_cache.GetProfileAttributesWithPath(profile_path, &entry)) |
| 417 return; |
| 418 |
| 423 base::string16 email_address; | 419 base::string16 email_address; |
| 424 if (!args->GetString(1, &email_address)) | 420 if (!args->GetString(1, &email_address)) |
| 425 return; | 421 return; |
| 426 | 422 |
| 427 std::string password; | 423 std::string password; |
| 428 if (!args->GetString(2, &password)) | 424 if (!args->GetString(2, &password)) |
| 429 return; | 425 return; |
| 430 | 426 |
| 431 const ProfileInfoCache& info_cache = | 427 authenticating_profile_path_ = profile_path; |
| 432 g_browser_process->profile_manager()->GetProfileInfoCache(); | 428 |
| 433 size_t profile_index = info_cache.GetIndexOfProfileWithPath(profile_path); | 429 size_t profile_index = info_cache.GetIndexOfProfileWithPath(profile_path); |
| 434 | |
| 435 if (profile_index == std::string::npos) { | |
| 436 NOTREACHED(); | |
| 437 return; | |
| 438 } | |
| 439 | |
| 440 authenticating_profile_index_ = profile_index; | |
| 441 if (LocalAuth::ValidateLocalAuthCredentials(profile_index, password)) { | 430 if (LocalAuth::ValidateLocalAuthCredentials(profile_index, password)) { |
| 442 ReportAuthenticationResult(true, ProfileMetrics::AUTH_LOCAL); | 431 ReportAuthenticationResult(true, ProfileMetrics::AUTH_LOCAL); |
| 443 return; | 432 return; |
| 444 } | 433 } |
| 445 | 434 |
| 446 email_address_ = email_address; | 435 email_address_ = base::UTF16ToUTF8(email_address); |
| 447 password_attempt_ = password; | 436 password_attempt_ = password; |
| 448 | 437 |
| 449 // This could be a mis-typed password or typing a new password while we | 438 // This could be a mis-typed password or typing a new password while we |
| 450 // still have a hash of the old one. The new way of checking a password | 439 // still have a hash of the old one. The new way of checking a password |
| 451 // change makes use of a token so we do that... if it's available. | 440 // change makes use of a token so we do that... if it's available. |
| 452 if (!oauth_client_) { | 441 if (!oauth_client_) { |
| 453 oauth_client_.reset(new gaia::GaiaOAuthClient( | 442 oauth_client_.reset(new gaia::GaiaOAuthClient( |
| 454 web_ui()->GetWebContents()->GetBrowserContext()->GetRequestContext())); | 443 web_ui()->GetWebContents()->GetBrowserContext()->GetRequestContext())); |
| 455 } | 444 } |
| 456 std::string token = info_cache.GetPasswordChangeDetectionTokenAtIndex( | 445 |
| 457 profile_index); | 446 std::string token = entry->GetPasswordChangeDetectionToken(); |
| 458 if (!token.empty()) { | 447 if (!token.empty()) { |
| 459 oauth_client_->GetTokenHandleInfo(token, kMaxOAuthRetries, this); | 448 oauth_client_->GetTokenHandleInfo(token, kMaxOAuthRetries, this); |
| 460 return; | 449 return; |
| 461 } | 450 } |
| 462 | 451 |
| 463 // In order to support the upgrade case where we have a local hash but no | 452 // In order to support the upgrade case where we have a local hash but no |
| 464 // password token, we fall back on (deprecated) ClientLogin. This will | 453 // password token, the user perform a full online reauth. |
| 465 // have to be removed in future versions as the service gets turned down | 454 UserManager::ShowReauthDialog(web_ui()->GetWebContents()->GetBrowserContext(), |
| 466 // but by then we'll have seamlessly updated the majority of users. | 455 email_address_); |
| 467 client_login_.reset(new GaiaAuthFetcher( | |
| 468 this, | |
| 469 GaiaConstants::kChromeSource, | |
| 470 web_ui()->GetWebContents()->GetBrowserContext()->GetRequestContext())); | |
| 471 | |
| 472 client_login_->StartClientLogin( | |
| 473 base::UTF16ToUTF8(email_address), | |
| 474 password, | |
| 475 GaiaConstants::kSyncService, | |
| 476 std::string(), | |
| 477 std::string(), | |
| 478 GaiaAuthFetcher::HostedAccountsAllowed); | |
| 479 } | 456 } |
| 480 | 457 |
| 481 void UserManagerScreenHandler::HandleRemoveUser(const base::ListValue* args) { | 458 void UserManagerScreenHandler::HandleRemoveUser(const base::ListValue* args) { |
| 482 DCHECK(args); | 459 DCHECK(args); |
| 483 const base::Value* profile_path_value; | 460 const base::Value* profile_path_value; |
| 484 if (!args->Get(0, &profile_path_value)) { | 461 if (!args->Get(0, &profile_path_value)) { |
| 485 NOTREACHED(); | 462 NOTREACHED(); |
| 486 return; | 463 return; |
| 487 } | 464 } |
| 488 | 465 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 } | 549 } |
| 573 | 550 |
| 574 void UserManagerScreenHandler::OnGetTokenInfoResponse( | 551 void UserManagerScreenHandler::OnGetTokenInfoResponse( |
| 575 scoped_ptr<base::DictionaryValue> token_info) { | 552 scoped_ptr<base::DictionaryValue> token_info) { |
| 576 // Password is unchanged so user just mistyped it. Ask again. | 553 // Password is unchanged so user just mistyped it. Ask again. |
| 577 ReportAuthenticationResult(false, ProfileMetrics::AUTH_FAILED); | 554 ReportAuthenticationResult(false, ProfileMetrics::AUTH_FAILED); |
| 578 } | 555 } |
| 579 | 556 |
| 580 void UserManagerScreenHandler::OnOAuthError() { | 557 void UserManagerScreenHandler::OnOAuthError() { |
| 581 // Password has changed. Go through online signin flow. | 558 // Password has changed. Go through online signin flow. |
| 582 // ... if we had it. Until then, use deprecated ClientLogin to validate | |
| 583 // the password. This will have to be changed soon. (TODO: bcwhite) | |
| 584 oauth_client_.reset(); | |
| 585 client_login_.reset(new GaiaAuthFetcher( | |
| 586 this, | |
| 587 GaiaConstants::kChromeSource, | |
| 588 web_ui()->GetWebContents()->GetBrowserContext()->GetRequestContext())); | |
| 589 | |
| 590 DCHECK(!email_address_.empty()); | 559 DCHECK(!email_address_.empty()); |
| 591 DCHECK(!password_attempt_.empty()); | 560 oauth_client_.reset(); |
| 592 client_login_->StartClientLogin( | 561 UserManager::ShowReauthDialog(web_ui()->GetWebContents()->GetBrowserContext(), |
| 593 base::UTF16ToUTF8(email_address_), | 562 email_address_); |
| 594 password_attempt_, | |
| 595 GaiaConstants::kSyncService, | |
| 596 std::string(), | |
| 597 std::string(), | |
| 598 GaiaAuthFetcher::HostedAccountsAllowed); | |
| 599 } | 563 } |
| 600 | 564 |
| 601 void UserManagerScreenHandler::OnNetworkError(int response_code) { | 565 void UserManagerScreenHandler::OnNetworkError(int response_code) { |
| 602 // Inconclusive but can't do real signin without being online anyway. | 566 // Inconclusive but can't do real signin without being online anyway. |
| 603 oauth_client_.reset(); | 567 oauth_client_.reset(); |
| 604 ReportAuthenticationResult(false, ProfileMetrics::AUTH_FAILED_OFFLINE); | 568 ReportAuthenticationResult(false, ProfileMetrics::AUTH_FAILED_OFFLINE); |
| 605 } | 569 } |
| 606 | 570 |
| 607 void UserManagerScreenHandler::OnClientLoginSuccess( | |
| 608 const ClientLoginResult& result) { | |
| 609 oauth_client_.reset(); | |
| 610 LocalAuth::SetLocalAuthCredentials(authenticating_profile_index_, | |
| 611 password_attempt_); | |
| 612 ReportAuthenticationResult(true, ProfileMetrics::AUTH_ONLINE); | |
| 613 } | |
| 614 | |
| 615 void UserManagerScreenHandler::OnClientLoginFailure( | |
| 616 const GoogleServiceAuthError& error) { | |
| 617 const GoogleServiceAuthError::State state = error.state(); | |
| 618 // Some "error" results mean the password was correct but some other action | |
| 619 // should be taken. For our purposes, we only care that the password was | |
| 620 // correct so count those as a success. | |
| 621 bool success = (state == GoogleServiceAuthError::NONE || | |
| 622 state == GoogleServiceAuthError::CAPTCHA_REQUIRED || | |
| 623 state == GoogleServiceAuthError::TWO_FACTOR || | |
| 624 state == GoogleServiceAuthError::ACCOUNT_DELETED || | |
| 625 state == GoogleServiceAuthError::ACCOUNT_DISABLED || | |
| 626 state == GoogleServiceAuthError::WEB_LOGIN_REQUIRED); | |
| 627 | |
| 628 // If the password was correct, the user must have changed it since the | |
| 629 // profile was locked. Save the password to streamline future unlocks. | |
| 630 if (success) { | |
| 631 DCHECK(!password_attempt_.empty()); | |
| 632 LocalAuth::SetLocalAuthCredentials(authenticating_profile_index_, | |
| 633 password_attempt_); | |
| 634 } | |
| 635 | |
| 636 bool offline = error.IsTransientError(); | |
| 637 ProfileMetrics::ProfileAuth failure_metric = | |
| 638 offline ? ProfileMetrics::AUTH_FAILED_OFFLINE : | |
| 639 ProfileMetrics::AUTH_FAILED; | |
| 640 ReportAuthenticationResult( | |
| 641 success, success ? ProfileMetrics::AUTH_ONLINE : failure_metric); | |
| 642 } | |
| 643 | |
| 644 void UserManagerScreenHandler::RegisterMessages() { | 571 void UserManagerScreenHandler::RegisterMessages() { |
| 645 web_ui()->RegisterMessageCallback(kJsApiUserManagerInitialize, | 572 web_ui()->RegisterMessageCallback(kJsApiUserManagerInitialize, |
| 646 base::Bind(&UserManagerScreenHandler::HandleInitialize, | 573 base::Bind(&UserManagerScreenHandler::HandleInitialize, |
| 647 base::Unretained(this))); | 574 base::Unretained(this))); |
| 648 web_ui()->RegisterMessageCallback(kJsApiUserManagerAddUser, | 575 web_ui()->RegisterMessageCallback(kJsApiUserManagerAddUser, |
| 649 base::Bind(&UserManagerScreenHandler::HandleAddUser, | 576 base::Bind(&UserManagerScreenHandler::HandleAddUser, |
| 650 base::Unretained(this))); | 577 base::Unretained(this))); |
| 651 web_ui()->RegisterMessageCallback(kJsApiUserManagerAuthLaunchUser, | 578 web_ui()->RegisterMessageCallback(kJsApiUserManagerAuthLaunchUser, |
| 652 base::Bind(&UserManagerScreenHandler::HandleAuthenticatedLaunchUser, | 579 base::Bind(&UserManagerScreenHandler::HandleAuthenticatedLaunchUser, |
| 653 base::Unretained(this))); | 580 base::Unretained(this))); |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 834 } | 761 } |
| 835 | 762 |
| 836 void UserManagerScreenHandler::ReportAuthenticationResult( | 763 void UserManagerScreenHandler::ReportAuthenticationResult( |
| 837 bool success, | 764 bool success, |
| 838 ProfileMetrics::ProfileAuth auth) { | 765 ProfileMetrics::ProfileAuth auth) { |
| 839 ProfileMetrics::LogProfileAuthResult(auth); | 766 ProfileMetrics::LogProfileAuthResult(auth); |
| 840 email_address_.clear(); | 767 email_address_.clear(); |
| 841 password_attempt_.clear(); | 768 password_attempt_.clear(); |
| 842 | 769 |
| 843 if (success) { | 770 if (success) { |
| 844 const ProfileInfoCache& info_cache = | |
| 845 g_browser_process->profile_manager()->GetProfileInfoCache(); | |
| 846 base::FilePath path = info_cache.GetPathOfProfileAtIndex( | |
| 847 authenticating_profile_index_); | |
| 848 profiles::SwitchToProfile( | 771 profiles::SwitchToProfile( |
| 849 path, | 772 authenticating_profile_path_, |
| 850 desktop_type_, | 773 desktop_type_, |
| 851 true, | 774 true, |
| 852 base::Bind(&UserManagerScreenHandler::OnSwitchToProfileComplete, | 775 base::Bind(&UserManagerScreenHandler::OnSwitchToProfileComplete, |
| 853 weak_ptr_factory_.GetWeakPtr()), | 776 weak_ptr_factory_.GetWeakPtr()), |
| 854 ProfileMetrics::SWITCH_PROFILE_UNLOCK); | 777 ProfileMetrics::SWITCH_PROFILE_UNLOCK); |
| 855 } else { | 778 } else { |
| 856 web_ui()->CallJavascriptFunction( | 779 web_ui()->CallJavascriptFunction( |
| 857 "cr.ui.Oobe.showSignInError", | 780 "cr.ui.Oobe.showSignInError", |
| 858 base::FundamentalValue(0), | 781 base::FundamentalValue(0), |
| 859 base::StringValue(l10n_util::GetStringUTF8( | 782 base::StringValue(l10n_util::GetStringUTF8( |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 916 Profile* profile, Profile::CreateStatus profile_create_status) { | 839 Profile* profile, Profile::CreateStatus profile_create_status) { |
| 917 Browser* browser = chrome::FindAnyBrowser(profile, false, desktop_type_); | 840 Browser* browser = chrome::FindAnyBrowser(profile, false, desktop_type_); |
| 918 if (browser && browser->window()) { | 841 if (browser && browser->window()) { |
| 919 OnBrowserWindowReady(browser); | 842 OnBrowserWindowReady(browser); |
| 920 } else { | 843 } else { |
| 921 registrar_.Add(this, | 844 registrar_.Add(this, |
| 922 chrome::NOTIFICATION_BROWSER_WINDOW_READY, | 845 chrome::NOTIFICATION_BROWSER_WINDOW_READY, |
| 923 content::NotificationService::AllSources()); | 846 content::NotificationService::AllSources()); |
| 924 } | 847 } |
| 925 } | 848 } |
| OLD | NEW |