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

Side by Side Diff: chrome/browser/ui/sync/one_click_signin_helper.cc

Issue 11938007: Don't use request user data during one-click sign in (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 7 years, 11 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
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/ui/sync/one_click_signin_helper.h" 5 #include "chrome/browser/ui/sync/one_click_signin_helper.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 break; 116 break;
117 default: 117 default:
118 NOTREACHED() << "Invalid auto_accept: " << auto_accept; 118 NOTREACHED() << "Invalid auto_accept: " << auto_accept;
119 break; 119 break;
120 } 120 }
121 121
122 UMA_HISTOGRAM_ENUMERATION("AutoLogin.Reverse", action, 122 UMA_HISTOGRAM_ENUMERATION("AutoLogin.Reverse", action,
123 one_click_signin::HISTOGRAM_MAX); 123 one_click_signin::HISTOGRAM_MAX);
124 } 124 }
125 125
126 void ClearPendingEmailOnIOThread(content::ResourceContext* context) {
127 ProfileIOData* io_data = ProfileIOData::FromResourceContext(context);
128 DCHECK(io_data);
129 if (io_data)
tim (not reviewing) 2013/01/23 02:07:52 Is there a reason you're handling this this way?
Roger Tawa OOO till Jul 10th 2013/01/25 20:14:10 Done.
130 io_data->set_reverse_autologin_pending_email("");
tim (not reviewing) 2013/01/23 02:07:52 nit - prefer std::string() to "", as it is more ex
Roger Tawa OOO till Jul 10th 2013/01/25 20:14:10 Done.
Roger Tawa OOO till Jul 10th 2013/01/25 20:14:10 Done.
131 }
132
126 // Determines the source of the sign in and the continue URL. Its either one 133 // Determines the source of the sign in and the continue URL. Its either one
127 // of the known sign in access point (first run, NTP, menu, settings) or its 134 // of the known sign in access point (first run, NTP, menu, settings) or its
128 // an implicit sign in via another Google property. In the former case, 135 // an implicit sign in via another Google property. In the former case,
129 // "service" is also checked to make sure its "chromiumsync". 136 // "service" is also checked to make sure its "chromiumsync".
130 SyncPromoUI::Source GetSigninSource(const GURL& url, GURL* continue_url) { 137 SyncPromoUI::Source GetSigninSource(const GURL& url, GURL* continue_url) {
131 std::string value; 138 std::string value;
132 chrome_common_net::GetValueForKeyInQuery(url, "service", &value); 139 chrome_common_net::GetValueForKeyInQuery(url, "service", &value);
133 bool possibly_an_explicit_signin = value == "chromiumsync"; 140 bool possibly_an_explicit_signin = value == "chromiumsync";
134 141
135 // Find the final continue URL for this sign in. In some cases, Gaia can 142 // Find the final continue URL for this sign in. In some cases, Gaia can
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 } 181 }
175 182
176 GURL origin = url.GetOrigin(); 183 GURL origin = url.GetOrigin();
177 if (origin == GURL("https://accounts.youtube.com") || 184 if (origin == GURL("https://accounts.youtube.com") ||
178 origin == GURL("https://accounts.blogger.com")) 185 origin == GURL("https://accounts.blogger.com"))
179 return true; 186 return true;
180 187
181 return false; 188 return false;
182 } 189 }
183 190
184 // This class is associated as user data with a given URLRequest object, in
185 // order to pass information from one response to another during the process
186 // of signing the user into their Gaia account. This class is only meant
187 // to be used from the IO thread.
188 class OneClickSigninRequestUserData : public base::SupportsUserData::Data {
189 public:
190 const std::string& email() const { return email_; }
191
192 // Associates signin information with the request. Overwrites existing
193 // information if any.
194 static void AssociateWithRequest(base::SupportsUserData* request,
195 const std::string& email);
196
197 // Gets the one-click sign in information associated with the request.
198 static OneClickSigninRequestUserData* FromRequest(
199 base::SupportsUserData* request);
200
201 private:
202 // Key used when setting this object on the request.
203 static const void* const kUserDataKey;
204
205 explicit OneClickSigninRequestUserData(const std::string& email)
206 : email_(email) {
207 }
208
209 std::string email_;
210
211 DISALLOW_COPY_AND_ASSIGN(OneClickSigninRequestUserData);
212 };
213
214 // static
215 void OneClickSigninRequestUserData::AssociateWithRequest(
216 base::SupportsUserData* request,
217 const std::string& email) {
218 request->SetUserData(kUserDataKey, new OneClickSigninRequestUserData(email));
219 }
220
221 // static
222 OneClickSigninRequestUserData* OneClickSigninRequestUserData::FromRequest(
223 base::SupportsUserData* request) {
224 return static_cast<OneClickSigninRequestUserData*>(
225 request->GetUserData(kUserDataKey));
226 }
227
228 const void* const OneClickSigninRequestUserData::kUserDataKey =
229 static_cast<const void* const>(
230 &OneClickSigninRequestUserData::kUserDataKey);
231
232 } // namespace 191 } // namespace
233 192
234 // The infobar asking the user if they want to use one-click sign in. 193 // The infobar asking the user if they want to use one-click sign in.
235 // TODO(rogerta): once we move to a web-based sign in flow, we can get rid 194 // TODO(rogerta): once we move to a web-based sign in flow, we can get rid
236 // of this infobar. 195 // of this infobar.
237 class OneClickInfoBarDelegateImpl : public OneClickSigninInfoBarDelegate { 196 class OneClickInfoBarDelegateImpl : public OneClickSigninInfoBarDelegate {
238 public: 197 public:
239 // Creates a one click signin delegate and adds it to |infobar_service|. 198 // Creates a one click signin delegate and adds it to |infobar_service|.
240 static void Create(InfoBarService* infobar_service, 199 static void Create(InfoBarService* infobar_service,
241 const std::string& session_index, 200 const std::string& session_index,
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 OneClickSigninHelper::OneClickSigninHelper(content::WebContents* web_contents) 361 OneClickSigninHelper::OneClickSigninHelper(content::WebContents* web_contents)
403 : content::WebContentsObserver(web_contents), 362 : content::WebContentsObserver(web_contents),
404 auto_accept_(AUTO_ACCEPT_NONE), 363 auto_accept_(AUTO_ACCEPT_NONE),
405 source_(SyncPromoUI::SOURCE_UNKNOWN) { 364 source_(SyncPromoUI::SOURCE_UNKNOWN) {
406 } 365 }
407 366
408 OneClickSigninHelper::~OneClickSigninHelper() { 367 OneClickSigninHelper::~OneClickSigninHelper() {
409 } 368 }
410 369
411 // static 370 // static
412 void OneClickSigninHelper::AssociateWithRequestForTesting(
413 base::SupportsUserData* request,
414 const std::string& email) {
415 OneClickSigninRequestUserData::AssociateWithRequest(request, email);
416 }
417
418 // static
419 bool OneClickSigninHelper::CanOffer(content::WebContents* web_contents, 371 bool OneClickSigninHelper::CanOffer(content::WebContents* web_contents,
420 CanOfferFor can_offer_for, 372 CanOfferFor can_offer_for,
421 const std::string& email, 373 const std::string& email,
422 int* error_message_id) { 374 int* error_message_id) {
423 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 375 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
424 VLOG(1) << "OneClickSigninHelper::CanOffer"; 376 VLOG(1) << "OneClickSigninHelper::CanOffer";
425 377
426 if (error_message_id) 378 if (error_message_id)
427 *error_message_id = 0; 379 *error_message_id = 0;
428 380
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 509
558 if (!SigninManager::AreSigninCookiesAllowed(io_data->GetCookieSettings())) 510 if (!SigninManager::AreSigninCookiesAllowed(io_data->GetCookieSettings()))
559 return DONT_OFFER; 511 return DONT_OFFER;
560 512
561 // The checks below depend on chrome already knowing what account the user 513 // The checks below depend on chrome already knowing what account the user
562 // signed in with. This happens only after receiving the response containing 514 // signed in with. This happens only after receiving the response containing
563 // the Google-Accounts-SignIn header. Until then, if there is even a chance 515 // the Google-Accounts-SignIn header. Until then, if there is even a chance
564 // that we want to connect the profile, chrome needs to tell Gaia that 516 // that we want to connect the profile, chrome needs to tell Gaia that
565 // it should offer the interstitial. Therefore missing one click data on 517 // it should offer the interstitial. Therefore missing one click data on
566 // the request means can offer is true. 518 // the request means can offer is true.
567 OneClickSigninRequestUserData* one_click_data = 519 const std::string& pending_email = io_data->reverse_autologin_pending_email();
568 OneClickSigninRequestUserData::FromRequest(request); 520 if (!pending_email.empty()) {
569 if (one_click_data) { 521 if (!SigninManager::IsAllowedUsername(pending_email,
570 if (!SigninManager::IsAllowedUsername(one_click_data->email(),
571 io_data->google_services_username_pattern()->GetValue())) { 522 io_data->google_services_username_pattern()->GetValue())) {
572 return DONT_OFFER; 523 return DONT_OFFER;
573 } 524 }
574 525
575 std::vector<std::string> rejected_emails = 526 std::vector<std::string> rejected_emails =
576 io_data->one_click_signin_rejected_email_list()->GetValue(); 527 io_data->one_click_signin_rejected_email_list()->GetValue();
577 if (std::count_if(rejected_emails.begin(), rejected_emails.end(), 528 if (std::count_if(rejected_emails.begin(), rejected_emails.end(),
578 std::bind2nd(std::equal_to<std::string>(), 529 std::bind2nd(std::equal_to<std::string>(),
579 one_click_data->email())) > 0) { 530 pending_email)) > 0) {
580 return DONT_OFFER; 531 return DONT_OFFER;
581 } 532 }
582 533
583 if (io_data->signin_names()->GetEmails().count( 534 if (io_data->signin_names()->GetEmails().count(
584 UTF8ToUTF16(one_click_data->email())) > 0) { 535 UTF8ToUTF16(pending_email)) > 0) {
585 return DONT_OFFER; 536 return DONT_OFFER;
586 } 537 }
587 } 538 }
588 539
589 return CAN_OFFER; 540 return CAN_OFFER;
590 } 541 }
591 542
592 // static 543 // static
593 void OneClickSigninHelper::InitializeFieldTrial() { 544 void OneClickSigninHelper::InitializeFieldTrial() {
594 scoped_refptr<base::FieldTrial> trial( 545 scoped_refptr<base::FieldTrial> trial(
595 base::FieldTrialList::FactoryGetFieldTrial("OneClickSignIn", 100, 546 base::FieldTrialList::FactoryGetFieldTrial("OneClickSignIn", 100,
596 "Standard", 2013, 9, 1, NULL)); 547 "Standard", 2013, 9, 1, NULL));
597 548
598 // For dev and beta, we'll give half the people the new experience. For 549 // For dev and beta, we'll give half the people the new experience. For
599 // stable, only 1%. These numbers are overridable on the server. 550 // stable, only 1%. These numbers are overridable on the server.
600 const bool kIsStableChannel = 551 const bool kIsStableChannel =
601 chrome::VersionInfo::GetChannel() == chrome::VersionInfo::CHANNEL_STABLE; 552 chrome::VersionInfo::GetChannel() == chrome::VersionInfo::CHANNEL_STABLE;
602 const int kBlueOnWhiteGroup = trial->AppendGroup("BlueOnWhite", 553 const int kBlueOnWhiteGroup = trial->AppendGroup("BlueOnWhite",
603 kIsStableChannel ? 1 : 50); 554 kIsStableChannel ? 1 : 50);
604 use_blue_on_white = trial->group() == kBlueOnWhiteGroup; 555 use_blue_on_white = trial->group() == kBlueOnWhiteGroup;
605 } 556 }
606 557
607 // static 558 // static
608 void OneClickSigninHelper::ShowInfoBarIfPossible(net::URLRequest* request, 559 void OneClickSigninHelper::ShowInfoBarIfPossible(net::URLRequest* request,
560 ProfileIOData* io_data,
609 int child_id, 561 int child_id,
610 int route_id) { 562 int route_id) {
611 std::string google_chrome_signin_value; 563 std::string google_chrome_signin_value;
612 std::string google_accounts_signin_value; 564 std::string google_accounts_signin_value;
613 request->GetResponseHeaderByName("Google-Chrome-SignIn", 565 request->GetResponseHeaderByName("Google-Chrome-SignIn",
614 &google_chrome_signin_value); 566 &google_chrome_signin_value);
615 request->GetResponseHeaderByName("Google-Accounts-SignIn", 567 request->GetResponseHeaderByName("Google-Accounts-SignIn",
616 &google_accounts_signin_value); 568 &google_accounts_signin_value);
617 569
618 if (!google_accounts_signin_value.empty() || 570 if (!google_accounts_signin_value.empty() ||
(...skipping 25 matching lines...) Expand all
644 TrimString(value, "\"", &email); 596 TrimString(value, "\"", &email);
645 } else if (key == "sessionindex") { 597 } else if (key == "sessionindex") {
646 session_index = value; 598 session_index = value;
647 } 599 }
648 } 600 }
649 601
650 // Later in the chain of this request, we'll need to check the email address 602 // Later in the chain of this request, we'll need to check the email address
651 // in the IO thread (see CanOfferOnIOThread). So save the email address as 603 // in the IO thread (see CanOfferOnIOThread). So save the email address as
652 // user data on the request (only for web-based flow). 604 // user data on the request (only for web-based flow).
653 if (SyncPromoUI::UseWebBasedSigninFlow() && !email.empty()) 605 if (SyncPromoUI::UseWebBasedSigninFlow() && !email.empty())
654 OneClickSigninRequestUserData::AssociateWithRequest(request, email); 606 io_data->set_reverse_autologin_pending_email(email);
655 607
656 if (!email.empty() || !session_index.empty()) { 608 if (!email.empty() || !session_index.empty()) {
657 VLOG(1) << "OneClickSigninHelper::ShowInfoBarIfPossible:" 609 VLOG(1) << "OneClickSigninHelper::ShowInfoBarIfPossible:"
658 << " email=" << email 610 << " email=" << email
659 << " sessionindex=" << session_index; 611 << " sessionindex=" << session_index;
660 } 612 }
661 613
662 // Parse Google-Chrome-SignIn. 614 // Parse Google-Chrome-SignIn.
663 AutoAccept auto_accept = AUTO_ACCEPT_NONE; 615 AutoAccept auto_accept = AUTO_ACCEPT_NONE;
664 SyncPromoUI::Source source = SyncPromoUI::SOURCE_UNKNOWN; 616 SyncPromoUI::Source source = SyncPromoUI::SOURCE_UNKNOWN;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 675
724 // TODO(mathp): The appearance of this infobar should be tested using a 676 // TODO(mathp): The appearance of this infobar should be tested using a
725 // browser_test. 677 // browser_test.
726 OneClickSigninHelper* helper = 678 OneClickSigninHelper* helper =
727 OneClickSigninHelper::FromWebContents(web_contents); 679 OneClickSigninHelper::FromWebContents(web_contents);
728 if (!helper) 680 if (!helper)
729 return; 681 return;
730 682
731 int error_message_id = 0; 683 int error_message_id = 0;
732 684
733 CanOfferFor can_offer_for =
734 (auto_accept != AUTO_ACCEPT_EXPLICIT &&
735 helper->auto_accept_ != AUTO_ACCEPT_EXPLICIT) ?
736 CAN_OFFER_FOR_INTERSTITAL_ONLY : CAN_OFFER_FOR_ALL;
737
738 if (!web_contents || !CanOffer(web_contents, can_offer_for, email,
739 &error_message_id)) {
740 VLOG(1) << "OneClickSigninHelper::ShowInfoBarUIThread: not offering";
741 if (helper && helper->error_message_.empty() && error_message_id != 0)
742 helper->error_message_ = l10n_util::GetStringUTF8(error_message_id);
743
744 return;
745 }
746
747 // Save the email in the one-click signin manager. The manager may 685 // Save the email in the one-click signin manager. The manager may
748 // not exist if the contents is incognito or if the profile is already 686 // not exist if the contents is incognito or if the profile is already
749 // connected to a Google account. 687 // connected to a Google account.
750 if (!session_index.empty()) 688 if (!session_index.empty())
751 helper->session_index_ = session_index; 689 helper->session_index_ = session_index;
752 690
753 if (!email.empty()) 691 if (!email.empty())
754 helper->email_ = email; 692 helper->email_ = email;
755 693
756 if (auto_accept != AUTO_ACCEPT_NONE) { 694 if (auto_accept != AUTO_ACCEPT_NONE) {
757 helper->auto_accept_ = auto_accept; 695 helper->auto_accept_ = auto_accept;
758 helper->source_ = source; 696 helper->source_ = source;
759 } 697 }
760 698
699 CanOfferFor can_offer_for =
700 (auto_accept != AUTO_ACCEPT_EXPLICIT &&
701 helper->auto_accept_ != AUTO_ACCEPT_EXPLICIT) ?
702 CAN_OFFER_FOR_INTERSTITAL_ONLY : CAN_OFFER_FOR_ALL;
703
704 if (!web_contents || !CanOffer(web_contents, can_offer_for, email,
705 &error_message_id)) {
706 VLOG(1) << "OneClickSigninHelper::ShowInfoBarUIThread: not offering";
707 if (helper && helper->error_message_.empty() && error_message_id != 0)
708 helper->error_message_ = l10n_util::GetStringUTF8(error_message_id);
709
710 return;
711 }
712
761 if (continue_url.is_valid()) { 713 if (continue_url.is_valid()) {
762 // When Gaia finally redirects to the continue URL, Gaia will add some 714 // When Gaia finally redirects to the continue URL, Gaia will add some
763 // extra query parameters. So ignore the parameters when checking to see 715 // extra query parameters. So ignore the parameters when checking to see
764 // if the user has continued. 716 // if the user has continued.
765 GURL::Replacements replacements; 717 GURL::Replacements replacements;
766 replacements.ClearQuery(); 718 replacements.ClearQuery();
767 helper->continue_url_ = continue_url.ReplaceComponents(replacements); 719 helper->continue_url_ = continue_url.ReplaceComponents(replacements);
768 } 720 }
769 } 721 }
770 722
(...skipping 17 matching lines...) Expand all
788 signin_tracker_.reset(); 740 signin_tracker_.reset();
789 } 741 }
790 742
791 void OneClickSigninHelper::CleanTransientState() { 743 void OneClickSigninHelper::CleanTransientState() {
792 VLOG(1) << "OneClickSigninHelper::CleanTransientState"; 744 VLOG(1) << "OneClickSigninHelper::CleanTransientState";
793 email_.clear(); 745 email_.clear();
794 password_.clear(); 746 password_.clear();
795 auto_accept_ = AUTO_ACCEPT_NONE; 747 auto_accept_ = AUTO_ACCEPT_NONE;
796 source_ = SyncPromoUI::SOURCE_UNKNOWN; 748 source_ = SyncPromoUI::SOURCE_UNKNOWN;
797 continue_url_ = GURL(); 749 continue_url_ = GURL();
750
751 // Post to IO thread to clear pending email.
752 Profile* profile =
753 Profile::FromBrowserContext(web_contents()->GetBrowserContext());
754 content::BrowserThread::PostTask(
755 content::BrowserThread::IO, FROM_HERE,
756 base::Bind(&ClearPendingEmailOnIOThread,
757 base::Unretained(profile->GetResourceContext())));
798 } 758 }
799 759
800 void OneClickSigninHelper::DidNavigateAnyFrame( 760 void OneClickSigninHelper::DidNavigateAnyFrame(
801 const content::LoadCommittedDetails& details, 761 const content::LoadCommittedDetails& details,
802 const content::FrameNavigateParams& params) { 762 const content::FrameNavigateParams& params) {
803 // We only need to scrape the password for Gaia logins. 763 // We only need to scrape the password for Gaia logins.
804 const content::PasswordForm& form = params.password_form; 764 const content::PasswordForm& form = params.password_form;
805 if (form.origin.is_valid() && 765 if (form.origin.is_valid() &&
806 gaia::IsGaiaSignonRealm(GURL(form.signon_realm))) { 766 gaia::IsGaiaSignonRealm(GURL(form.signon_realm))) {
807 VLOG(1) << "OneClickSigninHelper::DidNavigateAnyFrame: got password"; 767 VLOG(1) << "OneClickSigninHelper::DidNavigateAnyFrame: got password";
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
971 break; 931 break;
972 } 932 }
973 } 933 }
974 934
975 RedirectToNTP(); 935 RedirectToNTP();
976 } 936 }
977 937
978 void OneClickSigninHelper::SigninSuccess() { 938 void OneClickSigninHelper::SigninSuccess() {
979 RedirectToNTP(); 939 RedirectToNTP();
980 } 940 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698