Home | History | Annotate | Download | only in login
      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 
     33 namespace base {
     34 class DictionaryValue;
     35 class ListValue;
     36 }
     37 
     38 namespace chromeos {
     39 
     40 class CaptivePortalWindowProxy;
     41 class CoreOobeActor;
     42 class LocallyManagedUserCreationScreenHandler;
     43 class NativeWindowDelegate;
     44 class User;
     45 struct UserContext;
     46 
     47 // Helper class to pass initial parameters to the login screen.
     48 class 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.
     67 class 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.
     96 class 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.
    196 class 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