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

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

Issue 998513002: Revert of Remove OneClickSigninHelper since it is no longer used. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ocl
Patch Set: Created 5 years, 9 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #ifndef CHROME_BROWSER_UI_SYNC_ONE_CLICK_SIGNIN_HELPER_H_
6 #define CHROME_BROWSER_UI_SYNC_ONE_CLICK_SIGNIN_HELPER_H_
7
8 #include <string>
9
10 #include "base/gtest_prod_util.h"
11 #include "base/memory/weak_ptr.h"
12 #include "chrome/browser/signin/signin_promo.h"
13 #include "chrome/browser/sync/profile_sync_service_observer.h"
14 #include "chrome/browser/ui/sync/one_click_signin_sync_starter.h"
15 #include "components/signin/core/browser/signin_oauth_helper.h"
16 #include "content/public/browser/navigation_controller.h"
17 #include "content/public/browser/web_contents_observer.h"
18 #include "content/public/browser/web_contents_user_data.h"
19 #include "google_apis/gaia/google_service_auth_error.h"
20
21 class Browser;
22 class GURL;
23 class ProfileIOData;
24
25 namespace autofill {
26 struct PasswordForm;
27 }
28
29 namespace content {
30 class WebContents;
31 struct FrameNavigateParams;
32 struct LoadCommittedDetails;
33 }
34
35 namespace net {
36 class URLRequest;
37 }
38
39 namespace password_manager {
40 class PasswordManager;
41 }
42
43 // Per-tab one-click signin helper. When a user signs in to a Google service
44 // and the profile is not yet connected to a Google account, will start the
45 // process of helping the user connect his profile with one click. The process
46 // begins with an infobar and is followed with a confirmation dialog explaining
47 // more about what this means.
48 class OneClickSigninHelper
49 : public content::WebContentsObserver,
50 public content::WebContentsUserData<OneClickSigninHelper> {
51 public:
52 // Represents user's decision about sign in process.
53 enum AutoAccept {
54 // User decision not yet known. Assume cancel.
55 AUTO_ACCEPT_NONE,
56
57 // User has explicitly accepted to sign in. A bubble is shown with the
58 // option to start sync, configure it first, or abort.
59 AUTO_ACCEPT_ACCEPTED,
60
61 // User has explicitly accepted to sign in, but wants to configure sync
62 // settings before turning it on.
63 AUTO_ACCEPT_CONFIGURE,
64
65 // User has explicitly rejected to sign in. Furthermore, the user does
66 // not want to be prompted to see the interstitial again in this profile.
67 AUTO_ACCEPT_REJECTED_FOR_PROFILE,
68
69 // This is an explicit sign in from either first run, NTP, wrench menu,
70 // or settings page. The user will be signed in automatically with sync
71 // enabled using default settings.
72 AUTO_ACCEPT_EXPLICIT
73 };
74
75 // Return value of CanOfferOnIOThread().
76 enum Offer {
77 CAN_OFFER,
78 DONT_OFFER,
79 IGNORE_REQUEST
80 };
81
82 // Argument to CanOffer().
83 enum CanOfferFor {
84 CAN_OFFER_FOR_ALL,
85 CAN_OFFER_FOR_INTERSTITAL_ONLY,
86 CAN_OFFER_FOR_SECONDARY_ACCOUNT
87 // TODO(guohui): needs to handle adding secondary account through
88 // interstitial.
89 };
90
91 // Arguments used with StartSync function. base::Bind() cannot support too
92 // many args for performance reasons, so they are packaged up into a struct.
93 struct StartSyncArgs {
94 // Default contructor for testing only.
95 StartSyncArgs();
96 StartSyncArgs(Profile* profile,
97 Browser* browser,
98 OneClickSigninHelper::AutoAccept auto_accept,
99 const std::string& session_index,
100 const std::string& email,
101 const std::string& password,
102 const std::string& refresh_token,
103 content::WebContents* web_contents,
104 bool untrusted_confirmation_required,
105 signin_metrics::Source source,
106 OneClickSigninSyncStarter::Callback callback);
107 ~StartSyncArgs();
108
109 Profile* profile;
110 Browser* browser;
111 OneClickSigninHelper::AutoAccept auto_accept;
112 std::string session_index;
113 std::string email;
114 std::string password;
115 std::string refresh_token;
116
117 // Web contents in which the sync setup page should be displayed,
118 // if necessary. Can be NULL.
119 content::WebContents* web_contents;
120
121 OneClickSigninSyncStarter::ConfirmationRequired confirmation_required;
122 signin_metrics::Source source;
123 OneClickSigninSyncStarter::Callback callback;
124 };
125
126 // Wrapper to call OneClickSigninSyncStarter after fetching the refresh token
127 // if needed. Also verifies that the cookies are correct if no password is
128 // specified, and checks that the email from the cookies match the expected
129 // email address.
130 class SyncStarterWrapper : public SigninOAuthHelper::Consumer,
131 public chrome::BrowserListObserver {
132 public:
133 SyncStarterWrapper(
134 const OneClickSigninHelper::StartSyncArgs& args,
135 OneClickSigninSyncStarter::StartSyncMode start_mode);
136 ~SyncStarterWrapper() override;
137
138 void Start();
139
140 private:
141 void VerifyGaiaCookiesBeforeSignIn();
142 void OnGaiaCookiesFetched(const std::string session_index,
143 const net::CookieList& cookie_list);
144
145 // Virtual to be overridden in tests.
146 virtual void DisplayErrorBubble(const std::string& error_message);
147 virtual void StartSigninOAuthHelper();
148 virtual void StartOneClickSigninSyncStarter(
149 const std::string& email,
150 const std::string& refresh_token);
151
152 // Overriden from SigninOAuthHelper::Consumer.
153 void OnSigninOAuthInformationAvailable(
154 const std::string& email,
155 const std::string& display_email,
156 const std::string& refresh_token) override;
157 void OnSigninOAuthInformationFailure(
158 const GoogleServiceAuthError& error) override;
159
160 // Overriden from chrome::BrowserListObserver.
161 void OnBrowserRemoved(Browser* browser) override;
162
163 OneClickSigninHelper::StartSyncArgs args_;
164 chrome::HostDesktopType desktop_type_;
165 OneClickSigninSyncStarter::StartSyncMode start_mode_;
166 scoped_ptr<SigninOAuthHelper> signin_oauth_helper_;
167 base::WeakPtrFactory<SyncStarterWrapper> weak_pointer_factory_;
168
169 DISALLOW_COPY_AND_ASSIGN(SyncStarterWrapper);
170 };
171
172 static void LogHistogramValue(int action);
173
174 // Returns true if the one-click signin feature can be offered at this time.
175 // If |email| is not empty, then the profile is checked to see if it's
176 // already connected to a google account or if the user has already rejected
177 // one-click sign-in with this email, in which cases a one click signin
178 // should not be offered.
179 //
180 // If |can_offer_for| is |CAN_OFFER_FOR_INTERSTITAL_ONLY|, then only do the
181 // checks that would affect the interstitial page. Otherwise, do the checks
182 // that would affect the interstitial and the explicit sign ins.
183 //
184 // Returns in |error_message_id| an explanation as a string resource ID for
185 // why one-clicked cannot be offered. |error_message_id| is valid only if
186 // the return value is false. If no explanation is needed, |error_message_id|
187 // may be null.
188 static bool CanOffer(content::WebContents* web_contents,
189 CanOfferFor can_offer_for,
190 const std::string& email,
191 std::string* error_message);
192
193 // Returns true if the one-click signin feature can be offered at this time.
194 // It can be offered if the io_data is not in an incognito window and if the
195 // origin of |url| is a valid Gaia sign in origin. This function is meant
196 // to called only from the IO thread.
197 static Offer CanOfferOnIOThread(net::URLRequest* request,
198 ProfileIOData* io_data);
199
200 // Looks for the Google-Accounts-SignIn response header, and if found,
201 // tries to display an infobar in the tab contents identified by the
202 // child/route id.
203 static void ShowInfoBarIfPossible(net::URLRequest* request,
204 ProfileIOData* io_data,
205 int child_id,
206 int route_id);
207
208 // Handles cross account sign in error. If the supplied |email| does not match
209 // the last signed in email of the current profile, then Chrome will show a
210 // confirmation dialog before starting sync. It returns true if there is a
211 // cross account error, and false otherwise.
212 static bool HandleCrossAccountError(
213 Profile* profile,
214 const std::string& session_index,
215 const std::string& email,
216 const std::string& password,
217 const std::string& refresh_token,
218 OneClickSigninHelper::AutoAccept auto_accept,
219 signin_metrics::Source source,
220 OneClickSigninSyncStarter::StartSyncMode start_mode,
221 OneClickSigninSyncStarter::Callback sync_callback);
222
223 static void RedirectToNtpOrAppsPage(
224 content::WebContents* contents, signin_metrics::Source source);
225
226 // If the |source| is not settings page/webstore, redirects to
227 // the NTP/Apps page.
228 static void RedirectToNtpOrAppsPageIfNecessary(
229 content::WebContents* contents, signin_metrics::Source source);
230
231 // Remove the item currently at the top of the history list if it's
232 // the Gaia redirect URL. Due to limitations of the NavigationController
233 // this cannot be done until a new page becomes "current".
234 static void RemoveSigninRedirectURLHistoryItem(
235 content::WebContents* web_contents);
236
237 static void LogConfirmHistogramValue(int action);
238
239 private:
240 friend class content::WebContentsUserData<OneClickSigninHelper>;
241 friend class OneClickSigninHelperTest;
242 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIncognitoTest,
243 ShowInfoBarUIThreadIncognito);
244 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperTest,
245 SigninFromWebstoreWithConfigSyncfirst);
246 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperTest,
247 ShowSigninBubbleAfterSigninComplete);
248 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperTest, SigninCancelled);
249 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperTest, SigninFailed);
250 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperTest,
251 CleanTransientStateOnNavigate);
252 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest, CanOfferOnIOThread);
253 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
254 CanOfferOnIOThreadIncognito);
255 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
256 CanOfferOnIOThreadNoIOData);
257 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
258 CanOfferOnIOThreadBadURL);
259 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
260 CanOfferOnIOThreadDisabled);
261 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
262 CanOfferOnIOThreadSignedIn);
263 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
264 CanOfferOnIOThreadEmailNotAllowed);
265 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
266 CanOfferOnIOThreadEmailAlreadyUsed);
267 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
268 CreateTestProfileIOData);
269 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
270 CanOfferOnIOThreadWithRejectedEmail);
271 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
272 CanOfferOnIOThreadNoSigninCookies);
273 FRIEND_TEST_ALL_PREFIXES(OneClickSigninHelperIOTest,
274 CanOfferOnIOThreadDisabledByPolicy);
275
276 // Maximum number of navigations away from the set of valid Gaia URLs before
277 // clearing the internal state of the helper. This is necessary to support
278 // SAML-based accounts, but causes bug crbug.com/181163.
279 static const int kMaxNavigationsSince;
280
281 explicit OneClickSigninHelper(content::WebContents* web_contents);
282
283 ~OneClickSigninHelper() override;
284
285 // Returns true if the one-click signin feature can be offered at this time.
286 // It can be offered if the io_data is not in an incognito window and if the
287 // origin of |url| is a valid Gaia sign in origin. This function is meant
288 // to called only from the IO thread.
289 static Offer CanOfferOnIOThreadImpl(const GURL& url,
290 base::SupportsUserData* request,
291 ProfileIOData* io_data);
292
293 // The portion of ShowInfoBarIfPossible() that needs to run on the UI thread.
294 // |session_index| and |email| are extracted from the Google-Accounts-SignIn
295 // header. |auto_accept| is extracted from the Google-Chrome-SignIn header.
296 // |source| is used to determine which of the explicit sign in mechanism is
297 // being used.
298 //
299 // |continue_url| is where Gaia will continue to when the sign in process is
300 // done. For explicit sign ins, this is a URL chrome controls. For one-click
301 // sign in, this could be any google property. This URL is used to know
302 // when the sign process is over and to collect infomation from the user
303 // entered on the Gaia sign in page (for explicit sign ins).
304 static void ShowInfoBarUIThread(const std::string& session_index,
305 const std::string& email,
306 AutoAccept auto_accept,
307 signin_metrics::Source source,
308 const GURL& continue_url,
309 int child_id,
310 int route_id);
311
312 void RedirectToSignin();
313
314 // Clear all data member of the helper, except for the error.
315 void CleanTransientState();
316
317 // Unitests that use a TestingProfile should call this.
318 // Otherwise, clearing the pending e-mail crashes because the code expects
319 // a real ResourceContext rather than the MockResourceContext a
320 // TestingProfile provides.
321 void SetDoNotClearPendingEmailForTesting();
322
323 // In unit tests, disable starting the actual sync.
324 void set_do_not_start_sync_for_testing();
325
326 // Called when password has been submitted.
327 void PasswordSubmitted(const autofill::PasswordForm& form);
328
329 // content::WebContentsObserver overrides.
330 void DidStartNavigationToPendingEntry(
331 const GURL& url,
332 content::NavigationController::ReloadType reload_type) override;
333 void DidNavigateMainFrame(
334 const content::LoadCommittedDetails& details,
335 const content::FrameNavigateParams& params) override;
336 void DidStopLoading(content::RenderViewHost* render_view_host) override;
337
338 // Tracks if we are in the process of showing the signin or one click
339 // interstitial page. It's set to true the first time we load one of those
340 // pages and set to false when transient state is cleaned.
341 // Note: This should only be used for logging purposes.
342 bool showing_signin_;
343
344 // Information about the account that has just logged in.
345 std::string session_index_;
346 std::string email_;
347 std::string password_;
348 AutoAccept auto_accept_;
349 signin_metrics::Source source_;
350 bool switched_to_advanced_;
351 GURL continue_url_;
352 // The orignal continue URL after sync setup is complete.
353 GURL original_continue_url_;
354 std::string error_message_;
355
356 // Number of navigations since starting a sign in that is outside the
357 // the set of trusted Gaia URLs. Sign in attempts that include visits to
358 // one more untrusted will cause a modal dialog to appear asking the user
359 // to confirm, similar to the interstitial flow.
360 int untrusted_navigations_since_signin_visit_;
361
362 // Whether a Gaia URL during the sign in process was not handled by the
363 // dedicated sign in process (e.g. SAML login, which redirects to a
364 // non-google-controlled domain).
365 // This is set to true if at least one such URL is detected.
366 bool untrusted_confirmation_required_;
367
368 // Allows unittests to avoid accessing the ResourceContext for clearing a
369 // pending e-mail.
370 bool do_not_clear_pending_email_;
371
372 // Allows unittest to avoid starting sync for real.
373 bool do_not_start_sync_for_testing_;
374
375 base::WeakPtrFactory<OneClickSigninHelper> weak_pointer_factory_;
376
377 DISALLOW_COPY_AND_ASSIGN(OneClickSigninHelper);
378 };
379
380 #endif // CHROME_BROWSER_UI_SYNC_ONE_CLICK_SIGNIN_HELPER_H_
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/one_click_signin_view_controller.mm ('k') | chrome/browser/ui/sync/one_click_signin_helper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698