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/ui/sync/one_click_signin_helper.h" | 5 #include "chrome/browser/ui/sync/one_click_signin_helper.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
26 #include "chrome/browser/signin/signin_manager_factory.h" | 26 #include "chrome/browser/signin/signin_manager_factory.h" |
27 #include "chrome/browser/signin/signin_names_io_thread.h" | 27 #include "chrome/browser/signin/signin_names_io_thread.h" |
28 #include "chrome/browser/sync/profile_sync_service.h" | 28 #include "chrome/browser/sync/profile_sync_service.h" |
29 #include "chrome/browser/sync/profile_sync_service_factory.h" | 29 #include "chrome/browser/sync/profile_sync_service_factory.h" |
30 #include "chrome/browser/tab_contents/tab_util.h" | 30 #include "chrome/browser/tab_contents/tab_util.h" |
31 #include "chrome/browser/ui/browser_finder.h" | 31 #include "chrome/browser/ui/browser_finder.h" |
32 #include "chrome/browser/ui/browser_window.h" | 32 #include "chrome/browser/ui/browser_window.h" |
33 #include "chrome/browser/ui/sync/one_click_signin_histogram.h" | 33 #include "chrome/browser/ui/sync/one_click_signin_histogram.h" |
34 #include "chrome/browser/ui/sync/one_click_signin_sync_starter.h" | 34 #include "chrome/browser/ui/sync/one_click_signin_sync_starter.h" |
35 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 35 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
36 #include "chrome/common/chrome_notification_types.h" | |
36 #include "chrome/common/chrome_switches.h" | 37 #include "chrome/common/chrome_switches.h" |
37 #include "chrome/common/chrome_version_info.h" | 38 #include "chrome/common/chrome_version_info.h" |
38 #include "chrome/common/net/url_util.h" | 39 #include "chrome/common/net/url_util.h" |
39 #include "chrome/common/pref_names.h" | 40 #include "chrome/common/pref_names.h" |
40 #include "chrome/common/url_constants.h" | 41 #include "chrome/common/url_constants.h" |
41 #include "content/public/browser/browser_thread.h" | 42 #include "content/public/browser/browser_thread.h" |
42 #include "content/public/browser/page_navigator.h" | 43 #include "content/public/browser/page_navigator.h" |
43 #include "content/public/browser/web_contents.h" | 44 #include "content/public/browser/web_contents.h" |
44 #include "content/public/browser/web_contents_view.h" | 45 #include "content/public/browser/web_contents_view.h" |
45 #include "content/public/common/frame_navigate_params.h" | 46 #include "content/public/common/frame_navigate_params.h" |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
369 | 370 |
370 // static | 371 // static |
371 void OneClickSigninHelper::AssociateWithRequestForTesting( | 372 void OneClickSigninHelper::AssociateWithRequestForTesting( |
372 base::SupportsUserData* request, | 373 base::SupportsUserData* request, |
373 const std::string& email) { | 374 const std::string& email) { |
374 OneClickSigninRequestUserData::AssociateWithRequest(request, email); | 375 OneClickSigninRequestUserData::AssociateWithRequest(request, email); |
375 } | 376 } |
376 | 377 |
377 // static | 378 // static |
378 bool OneClickSigninHelper::CanOffer(content::WebContents* web_contents, | 379 bool OneClickSigninHelper::CanOffer(content::WebContents* web_contents, |
380 CanOfferFor can_offer_for, | |
379 const std::string& email, | 381 const std::string& email, |
380 bool check_connected) { | 382 int* error_message_id) { |
381 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 383 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
382 | 384 |
385 *error_message_id = 0; | |
386 | |
383 if (!web_contents) | 387 if (!web_contents) |
384 return false; | 388 return false; |
385 | 389 |
386 if (web_contents->GetBrowserContext()->IsOffTheRecord()) | 390 if (web_contents->GetBrowserContext()->IsOffTheRecord()) |
387 return false; | 391 return false; |
388 | 392 |
389 if (!ProfileSyncService::IsSyncEnabled()) | 393 if (!ProfileSyncService::IsSyncEnabled()) |
390 return false; | 394 return false; |
391 | 395 |
392 Profile* profile = | 396 Profile* profile = |
393 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 397 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
394 if (!profile) | 398 if (!profile) |
395 return false; | 399 return false; |
396 | 400 |
397 if (!profile->GetPrefs()->GetBoolean(prefs::kReverseAutologinEnabled)) | 401 if (can_offer_for == CAN_OFFER_FOR_INTERSTITAL_ONLY && |
402 !profile->GetPrefs()->GetBoolean(prefs::kReverseAutologinEnabled)) | |
398 return false; | 403 return false; |
399 | 404 |
400 if (!SigninManager::AreSigninCookiesAllowed(profile)) | 405 if (!SigninManager::AreSigninCookiesAllowed(profile)) |
401 return false; | 406 return false; |
402 | 407 |
403 if (check_connected) { | 408 if (!email.empty()) { |
404 SigninManager* manager = | 409 SigninManager* manager = |
405 SigninManagerFactory::GetForProfile(profile); | 410 SigninManagerFactory::GetForProfile(profile); |
406 if (!manager) | 411 if (!manager) |
407 return false; | 412 return false; |
408 | 413 |
409 if (!manager->GetAuthenticatedUsername().empty()) | 414 if (!manager->GetAuthenticatedUsername().empty()) { |
415 *error_message_id = IDS_SYNC_SETUP_ERROR; | |
410 return false; | 416 return false; |
417 } | |
411 | 418 |
412 // Make sure this username is not prohibited by policy. | 419 // Make sure this username is not prohibited by policy. |
413 if (!manager->IsAllowedUsername(email)) | 420 if (!manager->IsAllowedUsername(email)) { |
421 *error_message_id = IDS_SYNC_LOGIN_NAME_PROHIBITED; | |
414 return false; | 422 return false; |
423 } | |
415 | 424 |
416 // If some profile, not just the current one, is already connected to this | 425 // If some profile, not just the current one, is already connected to this |
417 // account, don't show the infobar. | 426 // account, don't show the infobar. |
418 if (g_browser_process) { | 427 if (g_browser_process) { |
419 ProfileManager* manager = g_browser_process->profile_manager(); | 428 ProfileManager* manager = g_browser_process->profile_manager(); |
420 if (manager) { | 429 if (manager) { |
421 string16 email16 = UTF8ToUTF16(email); | 430 string16 email16 = UTF8ToUTF16(email); |
422 ProfileInfoCache& cache = manager->GetProfileInfoCache(); | 431 ProfileInfoCache& cache = manager->GetProfileInfoCache(); |
423 | 432 |
424 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { | 433 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) { |
425 if (email16 == cache.GetUserNameOfProfileAtIndex(i)) | 434 if (email16 == cache.GetUserNameOfProfileAtIndex(i)) { |
435 *error_message_id = IDS_SYNC_USER_NAME_IN_USE_ERROR; | |
426 return false; | 436 return false; |
437 } | |
427 } | 438 } |
428 } | 439 } |
429 } | 440 } |
430 | 441 |
431 // If email was already rejected by this profile for one-click sign-in. | 442 // If email was already rejected by this profile for one-click sign-in. |
432 if (!email.empty()) { | 443 if (can_offer_for == CAN_OFFER_FOR_INTERSTITAL_ONLY) { |
433 const ListValue* rejected_emails = profile->GetPrefs()->GetList( | 444 const ListValue* rejected_emails = profile->GetPrefs()->GetList( |
434 prefs::kReverseAutologinRejectedEmailList); | 445 prefs::kReverseAutologinRejectedEmailList); |
435 if (!rejected_emails->empty()) { | 446 if (!rejected_emails->empty()) { |
436 const scoped_ptr<Value> email_value(new base::StringValue(email)); | 447 const scoped_ptr<Value> email_value(new base::StringValue(email)); |
437 base::ListValue::const_iterator iter = rejected_emails->Find( | 448 base::ListValue::const_iterator iter = rejected_emails->Find( |
438 *email_value); | 449 *email_value); |
439 if (iter != rejected_emails->end()) | 450 if (iter != rejected_emails->end()) |
440 return false; | 451 return false; |
441 } | 452 } |
442 } | 453 } |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
660 SyncPromoUI::Source source, | 671 SyncPromoUI::Source source, |
661 int child_id, | 672 int child_id, |
662 int route_id) { | 673 int route_id) { |
663 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 674 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
664 | 675 |
665 content::WebContents* web_contents = tab_util::GetWebContentsByID(child_id, | 676 content::WebContents* web_contents = tab_util::GetWebContentsByID(child_id, |
666 route_id); | 677 route_id); |
667 | 678 |
668 // TODO(mathp): The appearance of this infobar should be tested using a | 679 // TODO(mathp): The appearance of this infobar should be tested using a |
669 // browser_test. | 680 // browser_test. |
670 if (!web_contents || !CanOffer(web_contents, email, !email.empty())) { | 681 OneClickSigninHelper* helper = |
682 OneClickSigninHelper::FromWebContents(web_contents); | |
683 int error_message_id = 0; | |
684 | |
685 CanOfferFor can_offer_for = | |
686 (auto_accept != AUTO_ACCEPT_EXPLICIT && | |
687 helper->auto_accept_ != AUTO_ACCEPT_EXPLICIT) ? | |
688 CAN_OFFER_FOR_INTERSTITAL_ONLY : CAN_OFFER_FOR_ALL; | |
689 | |
690 if (!web_contents || !CanOffer(web_contents, can_offer_for, email, | |
691 &error_message_id)) { | |
671 VLOG(1) << "OneClickSigninHelper::ShowInfoBarUIThread: not offering"; | 692 VLOG(1) << "OneClickSigninHelper::ShowInfoBarUIThread: not offering"; |
693 if (helper && helper->error_message_.empty() && error_message_id != 0) | |
694 helper->error_message_ = l10n_util::GetStringUTF8(error_message_id); | |
695 | |
672 return; | 696 return; |
673 } | 697 } |
674 | 698 |
675 // Save the email in the one-click signin manager. The manager may | 699 // Save the email in the one-click signin manager. The manager may |
676 // not exist if the contents is incognito or if the profile is already | 700 // not exist if the contents is incognito or if the profile is already |
677 // connected to a Google account. | 701 // connected to a Google account. |
678 OneClickSigninHelper* helper = | |
679 OneClickSigninHelper::FromWebContents(web_contents); | |
680 if (helper) { | 702 if (helper) { |
681 if (!session_index.empty()) | 703 if (!session_index.empty()) |
682 helper->session_index_ = session_index; | 704 helper->session_index_ = session_index; |
683 | 705 |
684 if (!email.empty()) | 706 if (!email.empty()) |
685 helper->email_ = email; | 707 helper->email_ = email; |
686 | 708 |
687 helper->auto_accept_ = auto_accept; | 709 if (auto_accept != NO_AUTO_ACCEPT) { |
688 helper->source_ = source; | 710 helper->auto_accept_ = auto_accept; |
711 helper->source_ = source; | |
712 } | |
689 } | 713 } |
690 } | 714 } |
691 | 715 |
716 void OneClickSigninHelper::RedirectToNTP() { | |
717 // Redirect to NTP with sign in bubble visible. | |
718 content::WebContents* contents = web_contents(); | |
719 Profile* profile = | |
720 Profile::FromBrowserContext(contents->GetBrowserContext()); | |
721 PrefService* pref_service = profile->GetPrefs(); | |
722 pref_service->SetBoolean(prefs::kSyncPromoShowNTPBubble, true); | |
723 pref_service->SetString(prefs::kSyncPromoErrorMessage, error_message_); | |
Andrew T Wilson (Slow)
2012/12/03 14:54:49
I guess the way this works is once the NTP shows t
Roger Tawa OOO till Jul 10th
2012/12/03 22:26:54
correct.
| |
724 | |
725 contents->GetController().LoadURL(GURL(chrome::kChromeUINewTabURL), | |
726 content::Referrer(), | |
727 content::PAGE_TRANSITION_AUTO_TOPLEVEL, | |
728 std::string()); | |
729 | |
730 error_message_.clear(); | |
731 signin_tracker_.reset(); | |
732 } | |
733 | |
734 void OneClickSigninHelper::CleanTransientState() { | |
735 email_.clear(); | |
736 password_.clear(); | |
737 auto_accept_ = NO_AUTO_ACCEPT; | |
738 source_ = SyncPromoUI::SOURCE_UNKNOWN; | |
739 } | |
740 | |
692 void OneClickSigninHelper::DidNavigateAnyFrame( | 741 void OneClickSigninHelper::DidNavigateAnyFrame( |
693 const content::LoadCommittedDetails& details, | 742 const content::LoadCommittedDetails& details, |
694 const content::FrameNavigateParams& params) { | 743 const content::FrameNavigateParams& params) { |
695 // We only need to scrape the password for Gaia logins. | 744 // We only need to scrape the password for Gaia logins. |
696 const content::PasswordForm& form = params.password_form; | 745 const content::PasswordForm& form = params.password_form; |
697 if (form.origin.is_valid() && | 746 if (form.origin.is_valid() && |
698 gaia::IsGaiaSignonRealm(GURL(form.signon_realm))) { | 747 gaia::IsGaiaSignonRealm(GURL(form.signon_realm))) { |
699 VLOG(1) << "OneClickSigninHelper::DidNavigateAnyFrame: got password"; | 748 VLOG(1) << "OneClickSigninHelper::DidNavigateAnyFrame: got password"; |
700 password_ = UTF16ToUTF8(params.password_form.password_value); | 749 password_ = UTF16ToUTF8(params.password_form.password_value); |
701 } | 750 } |
702 } | 751 } |
703 | 752 |
704 void OneClickSigninHelper::DidStopLoading( | 753 void OneClickSigninHelper::DidStopLoading( |
705 content::RenderViewHost* render_view_host) { | 754 content::RenderViewHost* render_view_host) { |
755 // If the user left the sign in process, clear all members. | |
756 // TODO(rogerta): might need to allow some youtube URLs. | |
757 content::WebContents* contents = web_contents(); | |
758 if (!gaia::IsGaiaSignonRealm(contents->GetURL().GetOrigin())) { | |
759 CleanTransientState(); | |
760 return; | |
761 } | |
762 | |
763 if (!error_message_.empty()) { | |
764 RedirectToNTP(); | |
765 return; | |
766 } | |
767 | |
706 if (email_.empty() || password_.empty()) | 768 if (email_.empty() || password_.empty()) |
707 return; | 769 return; |
708 | 770 |
709 content::WebContents* contents = web_contents(); | |
710 Browser* browser = chrome::FindBrowserWithWebContents(contents); | 771 Browser* browser = chrome::FindBrowserWithWebContents(contents); |
711 InfoBarTabHelper* infobar_tab_helper = | 772 InfoBarTabHelper* infobar_tab_helper = |
712 InfoBarTabHelper::FromWebContents(contents); | 773 InfoBarTabHelper::FromWebContents(contents); |
713 | 774 |
714 switch (auto_accept_) { | 775 switch (auto_accept_) { |
715 case AUTO_ACCEPT: | 776 case AUTO_ACCEPT: |
716 browser->window()->ShowOneClickSigninBubble( | 777 browser->window()->ShowOneClickSigninBubble( |
717 base::Bind(&StartSync, browser, auto_accept_, session_index_, | 778 base::Bind(&StartSync, browser, auto_accept_, session_index_, |
718 email_, password_)); | 779 email_, password_)); |
719 break; | 780 break; |
(...skipping 25 matching lines...) Expand all Loading... | |
745 // If this explicit sign in is not from settings page, show the NTP after | 806 // If this explicit sign in is not from settings page, show the NTP after |
746 // sign in completes. In the case of the settings page, it will get closed | 807 // sign in completes. In the case of the settings page, it will get closed |
747 // by SyncSetupHandler. | 808 // by SyncSetupHandler. |
748 if (auto_accept_ == AUTO_ACCEPT_EXPLICIT && | 809 if (auto_accept_ == AUTO_ACCEPT_EXPLICIT && |
749 source_ != SyncPromoUI::SOURCE_SETTINGS) { | 810 source_ != SyncPromoUI::SOURCE_SETTINGS) { |
750 Profile* profile = | 811 Profile* profile = |
751 Profile::FromBrowserContext(contents->GetBrowserContext()); | 812 Profile::FromBrowserContext(contents->GetBrowserContext()); |
752 signin_tracker_.reset(new SigninTracker(profile, this)); | 813 signin_tracker_.reset(new SigninTracker(profile, this)); |
753 } | 814 } |
754 | 815 |
755 email_.clear(); | 816 CleanTransientState(); |
756 password_.clear(); | |
757 auto_accept_ = NO_AUTO_ACCEPT; | |
758 source_ = SyncPromoUI::SOURCE_UNKNOWN; | |
759 } | 817 } |
760 | 818 |
761 void OneClickSigninHelper::GaiaCredentialsValid() { | 819 void OneClickSigninHelper::GaiaCredentialsValid() { |
762 // Redirect to NTP with sign in bubble visible. | |
763 content::WebContents* contents = web_contents(); | |
764 Profile* profile = | |
765 Profile::FromBrowserContext(contents->GetBrowserContext()); | |
766 PrefService* pref_service = profile->GetPrefs(); | |
767 pref_service->SetBoolean(prefs::kSyncPromoShowNTPBubble, true); | |
768 | |
769 contents->GetController().LoadURL(GURL(chrome::kChromeUINewTabURL), | |
770 content::Referrer(), | |
771 content::PAGE_TRANSITION_AUTO_TOPLEVEL, | |
772 std::string()); | |
773 } | 820 } |
774 | 821 |
775 void OneClickSigninHelper::SigninFailed(const GoogleServiceAuthError& error) { | 822 void OneClickSigninHelper::SigninFailed(const GoogleServiceAuthError& error) { |
776 signin_tracker_.reset(); | 823 if (error_message_.empty() && !error.error_message().empty()) |
824 error_message_ = error.error_message(); | |
825 | |
826 if (error_message_.empty()) { | |
827 switch (error.state()) { | |
828 case GoogleServiceAuthError::NONE: | |
829 error_message_.clear(); | |
830 break; | |
831 case GoogleServiceAuthError::SERVICE_UNAVAILABLE: | |
832 error_message_ = l10n_util::GetStringUTF8(IDS_SYNC_UNRECOVERABLE_ERROR); | |
833 break; | |
834 case GoogleServiceAuthError::HOSTED_NOT_ALLOWED: | |
Andrew T Wilson (Slow)
2012/12/03 14:54:49
Remove this line since we just want to fall throug
Roger Tawa OOO till Jul 10th
2012/12/03 22:26:54
Done.
| |
835 default: | |
836 error_message_ = l10n_util::GetStringUTF8(IDS_SYNC_ERROR_SIGNING_IN); | |
837 break; | |
838 } | |
839 } | |
840 | |
841 RedirectToNTP(); | |
777 } | 842 } |
778 | 843 |
779 void OneClickSigninHelper::SigninSuccess() { | 844 void OneClickSigninHelper::SigninSuccess() { |
780 signin_tracker_.reset(); | 845 RedirectToNTP(); |
781 } | 846 } |
OLD | NEW |