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