1// Copyright (c) 2013 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_WEBUI_CHROMEOS_LOGIN_SIGNIN_SCREEN_HANDLER_H_
6#define CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_SIGNIN_SCREEN_HANDLER_H_
7
8#include <set>
9#include <string>
10
11#include "base/callback.h"
12#include "base/containers/hash_tables.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/memory/weak_ptr.h"
16#include "chrome/browser/chromeos/login/help_app_launcher.h"
17#include "chrome/browser/chromeos/login/login_display.h"
18#include "chrome/browser/chromeos/login/screens/error_screen_actor.h"
19#include "chrome/browser/chromeos/login/user_manager.h"
20#include "chrome/browser/chromeos/login/wallpaper_manager.h"
21#include "chrome/browser/chromeos/net/network_portal_detector.h"
22#include "chrome/browser/chromeos/settings/cros_settings.h"
23#include "chrome/browser/chromeos/system_key_event_listener.h"
24#include "chrome/browser/ui/webui/chromeos/login/base_screen_handler.h"
25#include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
26#include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
27#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
28#include "content/public/browser/notification_observer.h"
29#include "content/public/browser/notification_registrar.h"
30#include "content/public/browser/web_ui.h"
31#include "net/base/net_errors.h"
32
33namespace base {
34class DictionaryValue;
35class ListValue;
36}
37
38namespace chromeos {
39
40class CaptivePortalWindowProxy;
41class CoreOobeActor;
42class LocallyManagedUserCreationScreenHandler;
43class NativeWindowDelegate;
44class User;
45struct UserContext;
46
47// Helper class to pass initial parameters to the login screen.
48class LoginScreenContext {
49 public:
50  LoginScreenContext();
51  explicit LoginScreenContext(const base::ListValue* args);
52
53  void set_email(const std::string& email) { email_ = email; }
54  const std::string& email() const { return email_; }
55
56  void set_oobe_ui(bool oobe_ui) { oobe_ui_ = oobe_ui; }
57  bool oobe_ui() const { return oobe_ui_; }
58
59 private:
60  void Init();
61
62  std::string email_;
63  bool oobe_ui_;
64};
65
66// An interface for WebUILoginDisplay to call SigninScreenHandler.
67class LoginDisplayWebUIHandler {
68 public:
69  virtual void ClearAndEnablePassword() = 0;
70  virtual void ClearUserPodPassword() = 0;
71  virtual void OnLoginSuccess(const std::string& username) = 0;
72  virtual void OnUserRemoved(const std::string& username) = 0;
73  virtual void OnUserImageChanged(const User& user) = 0;
74  virtual void OnPreferencesChanged() = 0;
75  virtual void ResetSigninScreenHandlerDelegate() = 0;
76  virtual void ShowBannerMessage(const std::string& message) = 0;
77  virtual void ShowUserPodButton(const std::string& username,
78                                 const std::string& iconURL,
79                                 const base::Closure& click_callback) = 0;
80  virtual void ShowError(int login_attempts,
81                         const std::string& error_text,
82                         const std::string& help_link_text,
83                         HelpAppLauncher::HelpTopic help_topic_id) = 0;
84  virtual void ShowErrorScreen(LoginDisplay::SigninError error_id) = 0;
85  virtual void ShowGaiaPasswordChanged(const std::string& username) = 0;
86  virtual void ShowSigninUI(const std::string& email) = 0;
87  virtual void ShowPasswordChangedDialog(bool show_password_error) = 0;
88  // Show sign-in screen for the given credentials.
89  virtual void ShowSigninScreenForCreds(const std::string& username,
90                                        const std::string& password) = 0;
91 protected:
92  virtual ~LoginDisplayWebUIHandler() {}
93};
94
95// An interface for SigninScreenHandler to call WebUILoginDisplay.
96class SigninScreenHandlerDelegate {
97 public:
98  // Cancels current password changed flow.
99  virtual void CancelPasswordChangedFlow() = 0;
100
101  // Cancels user adding.
102  virtual void CancelUserAdding() = 0;
103
104  // Create a new Google account.
105  virtual void CreateAccount() = 0;
106
107  // Confirms sign up by provided credentials in |user_context|.
108  // Used for new user login via GAIA extension.
109  virtual void CompleteLogin(const UserContext& user_context) = 0;
110
111  // Sign in using username and password specified as a part of |user_context|.
112  // Used for both known and new users.
113  virtual void Login(const UserContext& user_context) = 0;
114
115  // Sign in into a retail mode session.
116  virtual void LoginAsRetailModeUser() = 0;
117
118  // Sign in into guest session.
119  virtual void LoginAsGuest() = 0;
120
121  // Sign in into the public account identified by |username|.
122  virtual void LoginAsPublicAccount(const std::string& username) = 0;
123
124  // Decrypt cryptohome using user provided |old_password|
125  // and migrate to new password.
126  virtual void MigrateUserData(const std::string& old_password) = 0;
127
128  // Load wallpaper for given |username|.
129  virtual void LoadWallpaper(const std::string& username) = 0;
130
131  // Loads the default sign-in wallpaper.
132  virtual void LoadSigninWallpaper() = 0;
133
134  // Notify the delegate when the sign-in UI is finished loading.
135  virtual void OnSigninScreenReady() = 0;
136
137  // Attempts to remove given user.
138  virtual void RemoveUser(const std::string& username) = 0;
139
140  // Ignore password change, remove existing cryptohome and
141  // force full sync of user data.
142  virtual void ResyncUserData() = 0;
143
144  // Shows Enterprise Enrollment screen.
145  virtual void ShowEnterpriseEnrollmentScreen() = 0;
146
147  // Shows Kiosk Enable screen.
148  virtual void ShowKioskEnableScreen() = 0;
149
150  // Shows Reset screen.
151  virtual void ShowResetScreen() = 0;
152
153  // Shows Reset screen.
154  virtual void ShowKioskAutolaunchScreen() = 0;
155
156  // Show wrong hwid screen.
157  virtual void ShowWrongHWIDScreen() = 0;
158
159  // Let the delegate know about the handler it is supposed to be using.
160  virtual void SetWebUIHandler(LoginDisplayWebUIHandler* webui_handler) = 0;
161
162  // Returns users list to be shown.
163  virtual const UserList& GetUsers() const = 0;
164
165  // Whether login as guest is available.
166  virtual bool IsShowGuest() const = 0;
167
168  // Whether login as guest is available.
169  virtual bool IsShowUsers() const = 0;
170
171  // Whether new user pod is available.
172  virtual bool IsShowNewUser() const = 0;
173
174  // Returns true if sign in is in progress.
175  virtual bool IsSigninInProgress() const = 0;
176
177  // Whether user sign in has completed.
178  virtual bool IsUserSigninCompleted() const = 0;
179
180  // Sets the displayed email for the next login attempt. If it succeeds,
181  // user's displayed email value will be updated to |email|.
182  virtual void SetDisplayEmail(const std::string& email) = 0;
183
184  // Signs out if the screen is currently locked.
185  virtual void Signout() = 0;
186
187  // Login to kiosk mode for app with |app_id|.
188  virtual void LoginAsKioskApp(const std::string& app_id) = 0;
189
190 protected:
191  virtual ~SigninScreenHandlerDelegate() {}
192};
193
194// A class that handles the WebUI hooks in sign-in screen in OobeDisplay
195// and LoginDisplay.
196class SigninScreenHandler
197    : public BaseScreenHandler,
198      public LoginDisplayWebUIHandler,
199      public SystemKeyEventListener::CapsLockObserver,
200      public content::NotificationObserver,
201      public NetworkStateInformer::NetworkStateInformerObserver,
202      public WallpaperManager::Observer {
203 public:
204  SigninScreenHandler(
205      const scoped_refptr<NetworkStateInformer>& network_state_informer,
206      ErrorScreenActor* error_screen_actor,
207      CoreOobeActor* core_oobe_actor,
208      GaiaScreenHandler* gaia_screen_handler);
209  virtual ~SigninScreenHandler();
210
211  // Shows the sign in screen.
212  void Show(const LoginScreenContext& context);
213
214  // Shows the login spinner UI for retail mode logins.
215  void ShowRetailModeLoginSpinner();
216
217  // Sets delegate to be used by the handler. It is guaranteed that valid
218  // delegate is set before Show() method will be called.
219  void SetDelegate(SigninScreenHandlerDelegate* delegate);
220
221  void SetNativeWindowDelegate(NativeWindowDelegate* native_window_delegate);
222
223  // NetworkStateInformer::NetworkStateInformerObserver implementation:
224  virtual void OnNetworkReady() OVERRIDE;
225  virtual void UpdateState(ErrorScreenActor::ErrorReason reason) OVERRIDE;
226
227  // Required Local State preferences.
228  static void RegisterPrefs(PrefRegistrySimple* registry);
229
230  void set_kiosk_enable_flow_aborted_callback_for_test(
231      const base::Closure& callback) {
232    kiosk_enable_flow_aborted_callback_for_test_ = callback;
233  }
234
235  // From WallpaperManager::Observer
236  virtual void OnWallpaperAnimationFinished(const std::string& email) OVERRIDE;
237
238 private:
239  enum UIState {
240    UI_STATE_UNKNOWN = 0,
241    UI_STATE_GAIA_SIGNIN,
242    UI_STATE_ACCOUNT_PICKER,
243  };
244
245  typedef base::hash_set<std::string> WebUIObservers;
246
247  friend class ReportDnsCacheClearedOnUIThread;
248  friend class LocallyManagedUserCreationScreenHandler;
249
250  void ShowImpl();
251
252  // Updates current UI of the signin screen according to |ui_state|
253  // argument.  Optionally it can pass screen initialization data via
254  // |params| argument.
255  void UpdateUIState(UIState ui_state, DictionaryValue* params);
256
257  void UpdateStateInternal(ErrorScreenActor::ErrorReason reason,
258                           bool force_update);
259  void SetupAndShowOfflineMessage(NetworkStateInformer::State state,
260                                  ErrorScreenActor::ErrorReason reason);
261  void HideOfflineMessage(NetworkStateInformer::State state,
262                          ErrorScreenActor::ErrorReason reason);
263  void ReloadGaiaScreen();
264
265  // BaseScreenHandler implementation:
266  virtual void DeclareLocalizedValues(LocalizedValuesBuilder* builder) OVERRIDE;
267  virtual void Initialize() OVERRIDE;
268  virtual gfx::NativeWindow GetNativeWindow() OVERRIDE;
269
270  // WebUIMessageHandler implementation:
271  virtual void RegisterMessages() OVERRIDE;
272
273  // LoginDisplayWebUIHandler implementation:
274  virtual void ClearAndEnablePassword() OVERRIDE;
275  virtual void ClearUserPodPassword() OVERRIDE;
276  virtual void OnLoginSuccess(const std::string& username) OVERRIDE;
277  virtual void OnUserRemoved(const std::string& username) OVERRIDE;
278  virtual void OnUserImageChanged(const User& user) OVERRIDE;
279  virtual void OnPreferencesChanged() OVERRIDE;
280  virtual void ResetSigninScreenHandlerDelegate() OVERRIDE;
281  virtual void ShowBannerMessage(const std::string& message) OVERRIDE;
282  virtual void ShowUserPodButton(const std::string& username,
283                                 const std::string& iconURL,
284                                 const base::Closure& click_callback) OVERRIDE;
285  virtual void ShowError(int login_attempts,
286                         const std::string& error_text,
287                         const std::string& help_link_text,
288                         HelpAppLauncher::HelpTopic help_topic_id) OVERRIDE;
289  virtual void ShowGaiaPasswordChanged(const std::string& username) OVERRIDE;
290  virtual void ShowSigninUI(const std::string& email) OVERRIDE;
291  virtual void ShowPasswordChangedDialog(bool show_password_error) OVERRIDE;
292  virtual void ShowErrorScreen(LoginDisplay::SigninError error_id) OVERRIDE;
293  virtual void ShowSigninScreenForCreds(const std::string& username,
294                                        const std::string& password) OVERRIDE;
295
296  // SystemKeyEventListener::CapsLockObserver overrides.
297  virtual void OnCapsLockChange(bool enabled) OVERRIDE;
298
299  // content::NotificationObserver implementation:
300  virtual void Observe(int type,
301                       const content::NotificationSource& source,
302                       const content::NotificationDetails& details) OVERRIDE;
303
304  // Shows signin screen after dns cache and cookie cleanup operations finish.
305  void ShowSigninScreenIfReady();
306
307  // Tells webui to load authentication extension. |force| is used to force the
308  // extension reloading, if it has already been loaded. |silent_load| is true
309  // for cases when extension should be loaded in the background and it
310  // shouldn't grab the focus. |offline| is true when offline version of the
311  // extension should be used.
312  void LoadAuthExtension(bool force, bool silent_load, bool offline);
313
314  // Updates authentication extension. Called when device settings that affect
315  // sign-in (allow BWSI and allow whitelist) are changed.
316  void UserSettingsChanged();
317  void UpdateAddButtonStatus();
318
319  // Restore input focus to current user pod.
320  void RefocusCurrentPod();
321
322  // WebUI message handlers.
323  void HandleCompleteAuthentication(const std::string& email,
324                                    const std::string& password,
325                                    const std::string& auth_code);
326  void HandleCompleteLogin(const std::string& typed_email,
327                           const std::string& password);
328  void HandleGetUsers();
329  void HandleAuthenticateUser(const std::string& username,
330                              const std::string& password);
331  void HandleLaunchDemoUser();
332  void HandleLaunchIncognito();
333  void HandleLaunchPublicAccount(const std::string& username);
334  void HandleOfflineLogin(const base::ListValue* args);
335  void HandleShutdownSystem();
336  void HandleLoadWallpaper(const std::string& email);
337  void HandleRebootSystem();
338  void HandleRemoveUser(const std::string& email);
339  void HandleShowAddUser(const base::ListValue* args);
340  void HandleToggleEnrollmentScreen();
341  void HandleToggleKioskEnableScreen();
342  void HandleToggleResetScreen();
343  void HandleToggleKioskAutolaunchScreen();
344  void HandleLaunchHelpApp(double help_topic_id);
345  void HandleCreateAccount();
346  void HandleAccountPickerReady();
347  void HandleWallpaperReady();
348  void HandleLoginWebuiReady();
349  void HandleSignOutUser();
350  void HandleNetworkErrorShown();
351  void HandleOpenProxySettings();
352  void HandleLoginVisible(const std::string& source);
353  void HandleCancelPasswordChangedFlow();
354  void HandleCancelUserAdding();
355  void HandleMigrateUserData(const std::string& password);
356  void HandleResyncUserData();
357  void HandleLoginUIStateChanged(const std::string& source, bool new_value);
358  void HandleUnlockOnLoginSuccess();
359  void HandleLoginScreenUpdate();
360  void HandleShowLoadingTimeoutError();
361  void HandleUpdateOfflineLogin(bool offline_login_active);
362  void HandleShowLocallyManagedUserCreationScreen();
363  void HandleFocusPod(const std::string& user_id);
364  void HandleLaunchKioskApp(const std::string& app_id);
365  void HandleCustomButtonClicked(const std::string& username);
366
367  // Fills |user_dict| with information about |user|.
368  static void FillUserDictionary(User* user,
369                                 bool is_owner,
370                                 DictionaryValue* user_dict);
371
372  // Sends user list to account picker.
373  void SendUserList(bool animated);
374
375  // Kick off cookie / local storage cleanup.
376  void StartClearingCookies(const base::Closure& on_clear_callback);
377  void OnCookiesCleared(base::Closure on_clear_callback);
378
379  // Kick off DNS cache flushing.
380  void StartClearingDnsCache();
381  void OnDnsCleared();
382
383  // Decides whether an auth extension should be pre-loaded. If it should,
384  // pre-loads it.
385  void MaybePreloadAuthExtension();
386
387  // Returns true iff
388  // (i)   log in is restricted to some user list,
389  // (ii)  all users in the restricted list are present.
390  bool AllWhitelistedUsersPresent();
391
392  // Cancels password changed flow - switches back to login screen.
393  // Called as a callback after cookies are cleared.
394  void CancelPasswordChangedFlowInternal();
395
396  // Returns current visible screen.
397  OobeUI::Screen GetCurrentScreen() const;
398
399  // Returns true if current visible screen is the Gaia sign-in page.
400  bool IsGaiaVisible() const;
401
402  // Returns true if current visible screen is the error screen over
403  // Gaia sign-in page.
404  bool IsGaiaHiddenByError() const;
405
406  // Returns true if current screen is the error screen over signin
407  // screen.
408  bool IsSigninScreenHiddenByError() const;
409
410  // Returns true if guest signin is allowed.
411  bool IsGuestSigninAllowed() const;
412
413  // Returns true if offline login is allowed.
414  bool IsOfflineLoginAllowed() const;
415
416  // Attempts login for test.
417  void SubmitLoginFormForTest();
418
419  // Update current input method (namely keyboard layout) to LRU by this user.
420  void SetUserInputMethod(const std::string& username);
421
422  // Invoked when auto enrollment check is finished to decide whether to
423  // continue kiosk enable flow. Kiosk enable flow is resumed when
424  // |should_auto_enroll| is false.
425  void ContinueKioskEnableFlow(bool should_auto_enroll);
426
427  // Shows signin screen for |email|.
428  void OnShowAddUser(const std::string& email);
429
430  GaiaScreenHandler::FrameState FrameState() const;
431  net::Error FrameError() const;
432
433  // Current UI state of the signin screen.
434  UIState ui_state_;
435
436  // A delegate that glues this handler with backend LoginDisplay.
437  SigninScreenHandlerDelegate* delegate_;
438
439  // A delegate used to get gfx::NativeWindow.
440  NativeWindowDelegate* native_window_delegate_;
441
442  // Whether screen should be shown right after initialization.
443  bool show_on_init_;
444
445  // Keeps whether screen should be shown for OOBE.
446  bool oobe_ui_;
447
448  // Is focus still stolen from Gaia page?
449  bool focus_stolen_;
450
451  // Has Gaia page silent load been started for the current sign-in attempt?
452  bool gaia_silent_load_;
453
454  // The active network at the moment when Gaia page was preloaded.
455  std::string gaia_silent_load_network_;
456
457  // Is account picker being shown for the first time.
458  bool is_account_picker_showing_first_time_;
459
460  // True if dns cache cleanup is done.
461  bool dns_cleared_;
462
463  // True if DNS cache task is already running.
464  bool dns_clear_task_running_;
465
466  // True if cookie jar cleanup is done.
467  bool cookies_cleared_;
468
469  // Help application used for help dialogs.
470  scoped_refptr<HelpAppLauncher> help_app_;
471
472  // Network state informer used to keep signin screen up.
473  scoped_refptr<NetworkStateInformer> network_state_informer_;
474
475  // Email to pre-populate with.
476  std::string email_;
477  // Emails of the users, whose passwords have recently been changed.
478  std::set<std::string> password_changed_for_;
479
480  // Test credentials.
481  std::string test_user_;
482  std::string test_pass_;
483  bool test_expects_complete_login_;
484
485  base::WeakPtrFactory<SigninScreenHandler> weak_factory_;
486
487  // Set to true once |LOGIN_WEBUI_VISIBLE| notification is observed.
488  bool webui_visible_;
489  bool preferences_changed_delayed_;
490
491  ErrorScreenActor* error_screen_actor_;
492  CoreOobeActor* core_oobe_actor_;
493
494  bool is_first_update_state_call_;
495  bool offline_login_active_;
496  NetworkStateInformer::State last_network_state_;
497
498  base::CancelableClosure update_state_closure_;
499  base::CancelableClosure connecting_closure_;
500
501  content::NotificationRegistrar registrar_;
502
503  // Whether there is an auth UI pending. This flag is set on receiving
504  // NOTIFICATION_AUTH_NEEDED and reset on either NOTIFICATION_AUTH_SUPPLIED or
505  // NOTIFICATION_AUTH_CANCELLED.
506  bool has_pending_auth_ui_;
507
508  scoped_ptr<CrosSettings::ObserverSubscription> allow_new_user_subscription_;
509  scoped_ptr<CrosSettings::ObserverSubscription> allow_guest_subscription_;
510
511  bool wait_for_auto_enrollment_check_;
512
513  base::Closure kiosk_enable_flow_aborted_callback_for_test_;
514
515  // Map of callbacks run when the custom button on a user pod is clicked.
516  std::map<std::string, base::Closure> user_pod_button_callback_map_;
517
518  // Non-owning ptr.
519  // TODO (ygorshenin@): remove this dependency.
520  GaiaScreenHandler* gaia_screen_handler_;
521
522  DISALLOW_COPY_AND_ASSIGN(SigninScreenHandler);
523};
524
525}  // namespace chromeos
526
527#endif  // CHROME_BROWSER_UI_WEBUI_CHROMEOS_LOGIN_SIGNIN_SCREEN_HANDLER_H_
528