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_CHROMEOS_LOGIN_LOGIN_PERFORMER_H_
6#define CHROME_BROWSER_CHROMEOS_LOGIN_LOGIN_PERFORMER_H_
7
8#include <string>
9
10#include "base/basictypes.h"
11#include "base/memory/weak_ptr.h"
12#include "chrome/browser/chromeos/login/authenticator.h"
13#include "chrome/browser/chromeos/login/login_status_consumer.h"
14#include "chrome/browser/chromeos/login/online_attempt_host.h"
15#include "chrome/browser/chromeos/login/user.h"
16#include "chrome/browser/profiles/profile_manager.h"
17#include "content/public/browser/notification_observer.h"
18#include "content/public/browser/notification_registrar.h"
19#include "google_apis/gaia/google_service_auth_error.h"
20
21namespace chromeos {
22
23// This class encapsulates sign in operations.
24// Sign in is performed in a way that offline auth is executed first.
25// Once offline auth is OK - user homedir is mounted, UI is launched.
26// At this point LoginPerformer |delegate_| is destroyed and it releases
27// LP instance ownership. LP waits for online login result.
28// If auth is succeeded, cookie fetcher is executed, LP instance deletes itself.
29//
30// If |delegate_| is not NULL it will handle error messages, password input.
31class LoginPerformer : public LoginStatusConsumer,
32                       public OnlineAttemptHost::Delegate {
33 public:
34  typedef enum AuthorizationMode {
35    // Authorization performed internally by Chrome.
36    AUTH_MODE_INTERNAL,
37    // Authorization performed by an extension.
38    AUTH_MODE_EXTENSION
39  } AuthorizationMode;
40
41  // Delegate class to get notifications from the LoginPerformer.
42  class Delegate : public LoginStatusConsumer {
43   public:
44    virtual ~Delegate() {}
45    virtual void WhiteListCheckFailed(const std::string& email) = 0;
46    virtual void PolicyLoadFailed() = 0;
47    virtual void OnOnlineChecked(const std::string& email, bool success) = 0;
48  };
49
50  explicit LoginPerformer(Delegate* delegate);
51  virtual ~LoginPerformer();
52
53  // LoginStatusConsumer implementation:
54  virtual void OnLoginFailure(const LoginFailure& error) OVERRIDE;
55  virtual void OnRetailModeLoginSuccess(
56      const UserContext& user_context) OVERRIDE;
57  virtual void OnLoginSuccess(
58      const UserContext& user_context,
59      bool pending_requests,
60      bool using_oauth) OVERRIDE;
61  virtual void OnOffTheRecordLoginSuccess() OVERRIDE;
62  virtual void OnPasswordChangeDetected() OVERRIDE;
63
64  // Performs a login for |user_context|.
65  // If auth_mode is AUTH_MODE_EXTENSION, there are no further auth checks,
66  // AUTH_MODE_INTERNAL will perform auth checks.
67  void PerformLogin(const UserContext& user_context,
68                    AuthorizationMode auth_mode);
69
70  // Performs locally managed user login with a given |user_context|.
71  void LoginAsLocallyManagedUser(const UserContext& user_context);
72
73  // Performs retail mode login.
74  void LoginRetailMode();
75
76  // Performs actions to prepare guest mode login.
77  void LoginOffTheRecord();
78
79  // Performs a login into the public account identified by |username|.
80  void LoginAsPublicAccount(const std::string& username);
81
82  // Migrates cryptohome using |old_password| specified.
83  void RecoverEncryptedData(const std::string& old_password);
84
85  // Reinitializes cryptohome with the new password.
86  void ResyncEncryptedData();
87
88  // Returns latest auth error.
89  const GoogleServiceAuthError& error() const {
90    return last_login_failure_.error();
91  }
92
93  // True if password change has been detected.
94  bool password_changed() { return password_changed_; }
95
96  // Number of times we've been called with OnPasswordChangeDetected().
97  // If user enters incorrect old password, same LoginPerformer instance will
98  // be called so callback count makes it possible to distinguish initial
99  // "password changed detected" event from further attempts to enter old
100  // password for cryptohome migration (when > 1).
101  int password_changed_callback_count() {
102    return password_changed_callback_count_;
103  }
104
105  void set_delegate(Delegate* delegate) { delegate_ = delegate; }
106
107  AuthorizationMode auth_mode() const { return auth_mode_; }
108
109 protected:
110  // Implements OnlineAttemptHost::Delegate.
111  virtual void OnChecked(const std::string& username, bool success) OVERRIDE;
112
113 private:
114  // Starts login completion of externally authenticated user.
115  void StartLoginCompletion();
116
117  // Starts authentication.
118  void StartAuthentication();
119
120  // Used for logging in.
121  scoped_refptr<Authenticator> authenticator_;
122
123  // Used to make auxiliary online check.
124  OnlineAttemptHost online_attempt_host_;
125
126  // Represents last login failure that was encountered when communicating to
127  // sign-in server. LoginFailure.LoginFailureNone() by default.
128  LoginFailure last_login_failure_;
129
130  // User credentials for the current login attempt.
131  UserContext user_context_;
132
133  // Notifications receiver.
134  Delegate* delegate_;
135
136  // True if password change has been detected.
137  // Once correct password is entered homedir migration is executed.
138  bool password_changed_;
139  int password_changed_callback_count_;
140
141  // Authorization mode type.
142  AuthorizationMode auth_mode_;
143
144  base::WeakPtrFactory<LoginPerformer> weak_factory_;
145
146  DISALLOW_COPY_AND_ASSIGN(LoginPerformer);
147};
148
149}  // namespace chromeos
150
151#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_LOGIN_PERFORMER_H_
152