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_SYNC_STARTER_H_
6#define CHROME_BROWSER_UI_SYNC_ONE_CLICK_SIGNIN_SYNC_STARTER_H_
7
8#include <string>
9
10#include "base/callback_forward.h"
11#include "base/gtest_prod_util.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/memory/weak_ptr.h"
14#include "chrome/browser/profiles/profile.h"
15#include "chrome/browser/ui/browser_list_observer.h"
16#include "chrome/browser/ui/host_desktop.h"
17#include "chrome/browser/ui/sync/profile_signin_confirmation_helper.h"
18#include "components/signin/core/browser/signin_tracker.h"
19#include "content/public/browser/web_contents_observer.h"
20
21class Browser;
22class ProfileSyncService;
23
24namespace content {
25class WebContents;
26}  // namespace content
27
28// Waits for successful sign-in notification from the signin manager and then
29// starts the sync machine.  Instances of this class delete themselves once
30// the job is done.
31class OneClickSigninSyncStarter : public SigninTracker::Observer,
32                                  public chrome::BrowserListObserver,
33                                  public content::WebContentsObserver {
34 public:
35  enum StartSyncMode {
36    // Starts the process of signing the user in with the SigninManager, and
37    // once completed automatically starts sync with all data types enabled.
38    SYNC_WITH_DEFAULT_SETTINGS,
39
40    // Starts the process of signing the user in with the SigninManager, and
41    // once completed redirects the user to the settings page to allow them
42    // to configure which data types to sync before sync is enabled.
43    CONFIGURE_SYNC_FIRST,
44
45    // Starts the process of re-authenticating the user via SigninManager,
46    // and once completed, redirects the user to the settings page, but doesn't
47    // display the configure sync UI.
48    SHOW_SETTINGS_WITHOUT_CONFIGURE,
49
50    // The process should be aborted because the undo button has been pressed.
51    UNDO_SYNC
52  };
53
54  enum ConfirmationRequired {
55    // No need to display a "post-signin" confirmation bubble (for example, if
56    // the user was doing a re-auth flow).
57    NO_CONFIRMATION,
58
59    // Signin flow redirected outside of trusted domains, so ask the user to
60    // confirm before signing in.
61    CONFIRM_UNTRUSTED_SIGNIN,
62
63    // Display a confirmation after signing in.
64    CONFIRM_AFTER_SIGNIN
65  };
66
67  // Result of the sync setup.
68  enum SyncSetupResult {
69    SYNC_SETUP_SUCCESS,
70    SYNC_SETUP_FAILURE
71  };
72
73  typedef base::Callback<void(SyncSetupResult)> Callback;
74
75  // |profile| must not be NULL, however |browser| can be. When using the
76  // OneClickSigninSyncStarter from a browser, provide both.
77  // If |display_confirmation| is true, the user will be prompted to confirm the
78  // signin before signin completes.
79  // |web_contents| is used to show the sync UI if it's showing a blank page
80  // and not about to be closed. It can be NULL.
81  // If |web_contents| is non-NULL and the |continue_url| is non-empty, the
82  // |web_contents| will be navigated to the |continue_url| once both signin and
83  // Sync setup are complete.
84  // |callback| is always executed before OneClickSigninSyncStarter is deleted.
85  // It can be empty.
86  OneClickSigninSyncStarter(Profile* profile,
87                            Browser* browser,
88                            const std::string& email,
89                            const std::string& password,
90                            const std::string& refresh_token,
91                            StartSyncMode start_mode,
92                            content::WebContents* web_contents,
93                            ConfirmationRequired display_confirmation,
94                            const GURL& continue_url,
95                            Callback callback);
96
97  // chrome::BrowserListObserver override.
98  virtual void OnBrowserRemoved(Browser* browser) OVERRIDE;
99
100  // If the |browser| argument is non-null, returns the pointer directly.
101  // Otherwise creates a new browser for the given profile on the given
102  // desktop, adds an empty tab and makes sure the browser is visible.
103  static Browser* EnsureBrowser(Browser* browser,
104                                Profile* profile,
105                                chrome::HostDesktopType desktop_type);
106
107 private:
108  friend class OneClickSigninSyncStarterTest;
109  FRIEND_TEST_ALL_PREFIXES(OneClickSigninSyncStarterTest, CallbackSigninFailed);
110  FRIEND_TEST_ALL_PREFIXES(OneClickSigninSyncStarterTest, CallbackNull);
111  FRIEND_TEST_ALL_PREFIXES(OneClickSigninSyncStarterTest, LoadContinueUrl);
112
113  virtual ~OneClickSigninSyncStarter();
114
115  // Initializes the internals of the OneClickSigninSyncStarter object. Can also
116  // be used to re-initialize the object to refer to a newly created profile.
117  void Initialize(Profile* profile, Browser* browser);
118
119  // SigninTracker::Observer override.
120  virtual void SigninFailed(const GoogleServiceAuthError& error) OVERRIDE;
121  virtual void SigninSuccess() OVERRIDE;
122  virtual void MergeSessionComplete(
123      const GoogleServiceAuthError& error) OVERRIDE;
124
125#if defined(ENABLE_CONFIGURATION_POLICY)
126  // User input handler for the signin confirmation dialog.
127  class SigninDialogDelegate
128    : public ui::ProfileSigninConfirmationDelegate {
129   public:
130    SigninDialogDelegate(
131        base::WeakPtr<OneClickSigninSyncStarter> sync_starter);
132    virtual ~SigninDialogDelegate();
133    virtual void OnCancelSignin() OVERRIDE;
134    virtual void OnContinueSignin() OVERRIDE;
135    virtual void OnSigninWithNewProfile() OVERRIDE;
136   private:
137    base::WeakPtr<OneClickSigninSyncStarter> sync_starter_;
138  };
139  friend class SigninDialogDelegate;
140
141  // Callback invoked once policy registration is complete. If registration
142  // fails, |dm_token| and |client_id| will be empty.
143  void OnRegisteredForPolicy(const std::string& dm_token,
144                             const std::string& client_id);
145
146  // Callback invoked when a policy fetch request has completed. |success| is
147  // true if policy was successfully fetched.
148  void OnPolicyFetchComplete(bool success);
149
150  // Called to create a new profile, which is then signed in with the
151  // in-progress auth credentials currently stored in this object.
152  void CreateNewSignedInProfile();
153
154  // Helper function that loads policy with the cached |dm_token_| and
155  // |client_id|, then completes the signin process.
156  void LoadPolicyWithCachedCredentials();
157
158  // Callback invoked once a profile is created, so we can complete the
159  // credentials transfer, load policy, and open the first window.
160  void CompleteInitForNewProfile(chrome::HostDesktopType desktop_type,
161                                 Profile* profile,
162                                 Profile::CreateStatus status);
163
164#endif  // defined(ENABLE_CONFIGURATION_POLICY)
165
166  // Cancels the in-progress signin for this profile.
167  void CancelSigninAndDelete();
168
169  // Callback invoked to check whether the user needs policy or if a
170  // confirmation is required (in which case we have to prompt the user first).
171  void ConfirmSignin(const std::string& oauth_token);
172
173  // Displays confirmation UI to the user if confirmation_required_ ==
174  // CONFIRM_UNTRUSTED_SIGNIN, otherwise completes the pending signin process.
175  void ConfirmAndSignin();
176
177  // Callback invoked once the user has responded to the signin confirmation UI.
178  // If response == UNDO_SYNC, the signin is cancelled, otherwise the pending
179  // signin is completed.
180  void UntrustedSigninConfirmed(StartSyncMode response);
181
182  // GetProfileSyncService returns non-NULL pointer if sync is enabled.
183  // There is a scenario when when ProfileSyncService discovers that sync is
184  // disabled during setup. In this case GetProfileSyncService will return NULL,
185  // but we still need to call PSS::SetSetupInProgress(false). For this purpose
186  // call FinishProfileSyncServiceSetup() function.
187  ProfileSyncService* GetProfileSyncService();
188
189  void FinishProfileSyncServiceSetup();
190
191  // Displays the settings UI and brings up the advanced sync settings
192  // dialog if |configure_sync| is true. The web contents provided to the
193  // constructor is used if it's showing a blank page and not about to be
194  // closed. Otherwise, a new tab or an existing settings tab is used.
195  void ShowSettingsPage(bool configure_sync);
196
197  // Displays a settings page in the provided web contents. |sub_page| can be
198  // empty to show the main settings page.
199  void ShowSettingsPageInWebContents(content::WebContents* contents,
200                                     const std::string& sub_page);
201
202  // Shows the post-signin confirmation bubble. If |custom_message| is empty,
203  // the default "You are signed in" message is displayed.
204  void DisplayFinalConfirmationBubble(const base::string16& custom_message);
205
206  // Loads the |continue_url_| in the current tab.
207  void LoadContinueUrl();
208
209  Profile* profile_;
210  Browser* browser_;
211  scoped_ptr<SigninTracker> signin_tracker_;
212  StartSyncMode start_mode_;
213  chrome::HostDesktopType desktop_type_;
214  bool force_same_tab_navigation_;
215  ConfirmationRequired confirmation_required_;
216  GURL continue_url_;
217
218  // Callback executed when sync setup succeeds or fails.
219  Callback sync_setup_completed_callback_;
220
221#if defined(ENABLE_CONFIGURATION_POLICY)
222  // Policy credentials we keep while determining whether to create
223  // a new profile for an enterprise user or not.
224  std::string dm_token_;
225  std::string client_id_;
226#endif
227
228  base::WeakPtrFactory<OneClickSigninSyncStarter> weak_pointer_factory_;
229
230  DISALLOW_COPY_AND_ASSIGN(OneClickSigninSyncStarter);
231};
232
233
234#endif  // CHROME_BROWSER_UI_SYNC_ONE_CLICK_SIGNIN_SYNC_STARTER_H_
235