1// Copyright (c) 2011 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_CHROMEOS_LOGIN_LOGIN_PERFORMER_H_
6#define CHROME_BROWSER_CHROMEOS_LOGIN_LOGIN_PERFORMER_H_
7#pragma once
8
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/memory/ref_counted.h"
13#include "base/task.h"
14#include "chrome/browser/chromeos/login/authenticator.h"
15#include "chrome/browser/chromeos/login/login_status_consumer.h"
16#include "chrome/browser/chromeos/login/signed_settings_helper.h"
17#include "chrome/browser/profiles/profile_manager.h"
18#include "chrome/common/net/gaia/google_service_auth_error.h"
19#include "content/common/notification_observer.h"
20#include "content/common/notification_registrar.h"
21
22namespace chromeos {
23
24// This class encapsulates sign in operations.
25// Sign in is performed in a way that offline auth is executed first.
26// Once offline auth is OK - user homedir is mounted, UI is launched.
27// At this point LoginPerformer |delegate_| is destroyed and it releases
28// LP instance ownership. LP waits for online login result.
29// If auth is succeeded, cookie fetcher is executed, LP instance deletes itself.
30//
31// If online login operation fails that means:
32// (1) User password has changed. Ask user for the new password.
33// (2) User password has changed and/or CAPTCHA input is required.
34// (3) User account is deleted/disabled/not signed up.
35// (4) Timeout/service unavailable/connection failed.
36//
37// Actions:
38// (1)-(3): Request screen lock.
39// (1) Ask for new user password.
40// (2) Ask for new user password and/or CAPTCHA.
41// (3) Display error message and allow "Sign Out" as the only action.
42// (4) Delete LP instance since offline auth was OK.
43//
44// If |delegate_| is not NULL it will handle error messages,
45// CAPTCHA dialog, password input.
46// If |delegate_| is NULL that does mean that LoginPerformer instance
47// is waiting for successful online login or blocked on online login failure.
48// In case of failure password/captcha
49// input & error messages display is dedicated to ScreenLocker instance.
50//
51// 2 things make LoginPerfrormer instance exist longer:
52// 1. ScreenLock active (pending correct new password input)
53// 2. Pending online auth request.
54class LoginPerformer : public LoginStatusConsumer,
55                       public SignedSettingsHelper::Callback,
56                       public NotificationObserver,
57                       public ProfileManager::Observer {
58 public:
59  // Delegate class to get notifications from the LoginPerformer.
60  class Delegate : public LoginStatusConsumer {
61   public:
62    virtual ~Delegate() {}
63    virtual void WhiteListCheckFailed(const std::string& email) = 0;
64  };
65
66  explicit LoginPerformer(Delegate* delegate);
67  virtual ~LoginPerformer();
68
69  // Returns the default instance if it has been created.
70  // This instance is owned by delegate_ till it's destroyed.
71  // When LP instance lives by itself it's used by ScreenLocker instance.
72  static LoginPerformer* default_performer() {
73    return default_performer_;
74  }
75
76  // LoginStatusConsumer implementation:
77  virtual void OnLoginFailure(const LoginFailure& error);
78  virtual void OnLoginSuccess(
79      const std::string& username,
80      const std::string& password,
81      const GaiaAuthConsumer::ClientLoginResult& credentials,
82      bool pending_requests);
83  virtual void OnOffTheRecordLoginSuccess();
84  virtual void OnPasswordChangeDetected(
85      const GaiaAuthConsumer::ClientLoginResult& credentials);
86
87  // SignedSettingsHelper::Callback implementation:
88  virtual void OnCheckWhitelistCompleted(SignedSettings::ReturnCode code,
89                                         const std::string& email);
90
91  // NotificationObserver implementation:
92  virtual void Observe(NotificationType type,
93                       const NotificationSource& source,
94                       const NotificationDetails& details);
95
96  // Performs login with the |username| and |password| specified.
97  void Login(const std::string& username, const std::string& password);
98
99  // Performs actions to prepare Guest mode login.
100  void LoginOffTheRecord();
101
102  // Migrates cryptohome using |old_password| specified.
103  void RecoverEncryptedData(const std::string& old_password);
104
105  // Reinitializes cryptohome with the new password.
106  void ResyncEncryptedData();
107
108  // Returns latest auth error.
109  const GoogleServiceAuthError& error() const {
110    return last_login_failure_.error();
111  }
112
113  // True if last login operation has timed out.
114  bool login_timed_out() {
115    return last_login_failure_.reason() == LoginFailure::LOGIN_TIMED_OUT;
116  }
117
118  void set_captcha(const std::string& captcha) { captcha_ = captcha; }
119  void set_delegate(Delegate* delegate) { delegate_ = delegate; }
120
121 private:
122  // ProfeleManager::Observer implementation:
123  void OnProfileCreated(Profile* profile);
124
125  // Requests screen lock and subscribes to screen lock notifications.
126  void RequestScreenLock();
127
128  // Requests screen unlock.
129  void RequestScreenUnlock();
130
131  // Resolves initial LoginFailure::NETWORK_AUTH_FAILED error i.e.
132  // when screen is not locked yet.
133  void ResolveInitialNetworkAuthFailure();
134
135  // Resolves LoginFailure when screen is locked.
136  void ResolveLockLoginFailure();
137
138  // Resolves LoginFailure::NETWORK_AUTH_FAILED error when screen is locked.
139  // Uses ScreenLocker to show error message based on |last_login_failure_|.
140  void ResolveLockNetworkAuthFailure();
141
142  // Resolve ScreenLock changed state.
143  void ResolveScreenLocked();
144  void ResolveScreenUnlocked();
145
146  // Starts authentication.
147  void StartAuthentication();
148
149  // Default performer. Will be used by ScreenLocker.
150  static LoginPerformer* default_performer_;
151
152  // Used for logging in.
153  scoped_refptr<Authenticator> authenticator_;
154
155  // Represents last login failure that was encountered when communicating to
156  // sign-in server. LoginFailure.None() by default.
157  LoginFailure last_login_failure_;
158
159  // String entered by the user as an answer to a CAPTCHA challenge.
160  std::string captcha_;
161
162  // Token representing the specific CAPTCHA challenge.
163  std::string captcha_token_;
164
165  // Cached credentials data when password change is detected.
166  GaiaAuthConsumer::ClientLoginResult cached_credentials_;
167
168  // Username and password for the current login attempt.
169  std::string username_;
170  std::string password_;
171
172  // Notifications receiver.
173  Delegate* delegate_;
174
175  // True if password change has been detected.
176  // Once correct password is entered homedir migration is executed.
177  bool password_changed_;
178
179  // Used for ScreenLock notifications.
180  NotificationRegistrar registrar_;
181
182  // True if LoginPerformer has requested screen lock. Used to distinguish
183  // such requests with cases when screen is locked on its own.
184  bool screen_lock_requested_;
185
186  // True if LoginPerformer instance is waiting for the initial (very first one)
187  // online authentication response. Used to distinguish cases when screen
188  // is locked during that stage. No need to resolve screen lock action then.
189  bool initial_online_auth_pending_;
190
191  GaiaAuthConsumer::ClientLoginResult credentials_;
192
193  ScopedRunnableMethodFactory<LoginPerformer> method_factory_;
194
195  DISALLOW_COPY_AND_ASSIGN(LoginPerformer);
196};
197
198}  // namespace chromeos
199
200#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_LOGIN_PERFORMER_H_
201