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// The signin manager encapsulates some functionality tracking
6// which user is signed in. See SigninManagerBase for full description of
7// responsibilities. The class defined in this file provides functionality
8// required by all platforms except Chrome OS.
9//
10// When a user is signed in, a ClientLogin request is run on their behalf.
11// Auth tokens are fetched from Google and the results are stored in the
12// TokenService.
13// TODO(tim): Bug 92948, 226464. ClientLogin is all but gone from use.
14
15#ifndef CHROME_BROWSER_SIGNIN_SIGNIN_MANAGER_H_
16#define CHROME_BROWSER_SIGNIN_SIGNIN_MANAGER_H_
17
18#if defined(OS_CHROMEOS)
19// On Chrome OS, SigninManagerBase is all that exists.
20#include "chrome/browser/signin/signin_manager_base.h"
21
22#else
23
24#include <string>
25
26#include "base/compiler_specific.h"
27#include "base/gtest_prod_util.h"
28#include "base/logging.h"
29#include "base/memory/scoped_ptr.h"
30#include "base/observer_list.h"
31#include "base/prefs/pref_change_registrar.h"
32#include "base/prefs/pref_member.h"
33#include "chrome/browser/profiles/profile.h"
34#include "chrome/browser/signin/signin_internals_util.h"
35#include "chrome/browser/signin/signin_manager_base.h"
36#include "components/browser_context_keyed_service/browser_context_keyed_service.h"
37#include "content/public/browser/notification_observer.h"
38#include "content/public/browser/notification_registrar.h"
39#include "google_apis/gaia/gaia_auth_consumer.h"
40#include "google_apis/gaia/google_service_auth_error.h"
41#include "net/cookies/canonical_cookie.h"
42
43class CookieSettings;
44class GaiaAuthFetcher;
45class ProfileIOData;
46class PrefService;
47class SigninAccountIdHelper;
48class SigninGlobalError;
49class SigninManagerDelegate;
50
51class SigninManager : public SigninManagerBase,
52                      public GaiaAuthConsumer,
53                      public content::NotificationObserver {
54 public:
55  // The callback invoked once the OAuth token has been fetched during signin,
56  // but before the profile transitions to the "signed-in" state. This allows
57  // callers to load policy and prompt the user appropriately before completing
58  // signin. The callback is passed the just-fetched OAuth login refresh token.
59  typedef base::Callback<void(const std::string&)> OAuthTokenFetchedCallback;
60
61  // Returns true if |url| is a web signin URL and should be hosted in an
62  // isolated, privileged signin process.
63  static bool IsWebBasedSigninFlowURL(const GURL& url);
64
65  // This is used to distinguish URLs belonging to the special web signin flow
66  // running in the special signin process from other URLs on the same domain.
67  // We do not grant WebUI privilieges / bindings to this process or to URLs of
68  // this scheme; enforcement of privileges is handled separately by
69  // OneClickSigninHelper.
70  static const char* kChromeSigninEffectiveSite;
71
72  explicit SigninManager(scoped_ptr<SigninManagerDelegate> delegate);
73  virtual ~SigninManager();
74
75  // Returns true if the username is allowed based on the policy string.
76  static bool IsUsernameAllowedByPolicy(const std::string& username,
77                                        const std::string& policy);
78
79  // Attempt to sign in this user with existing credentials from the cookie jar.
80  // |session_index| indicates which user account to use if the cookie jar
81  // contains a multi-login session. Otherwise the end result of this call is
82  // the same as StartSignIn().
83  // If non-null, the passed |signin_complete| callback is invoked once signin
84  // has been completed and the oauth login token has been generated - the
85  // callback will not be invoked if no token is generated (either because of
86  // a failed signin or because web-based signin is not enabled).
87  // The callback should invoke SignOut() or CompletePendingSignin() to either
88  // continue or cancel the in-process signin.
89  virtual void StartSignInWithCredentials(
90      const std::string& session_index,
91      const std::string& username,
92      const std::string& password,
93      const OAuthTokenFetchedCallback& oauth_fetched_callback);
94
95  // Attempt to sign in this user with the given oauth code. The cookie jar
96  // may not be set up properly for the same user, thus will call the
97  // mergeSession endpoint to populate the cookie jar.
98  virtual void StartSignInWithOAuthCode(
99      const std::string& username,
100      const std::string& password,
101      const std::string& oauth_code,
102      const OAuthTokenFetchedCallback& callback);
103
104  // Copies auth credentials from one SigninManager to this one. This is used
105  // when creating a new profile during the signin process to transfer the
106  // in-progress credentials to the new profile.
107  virtual void CopyCredentialsFrom(const SigninManager& source);
108
109  // Sign a user out, removing the preference, erasing all keys
110  // associated with the user, and canceling all auth in progress.
111  virtual void SignOut();
112
113  // On platforms where SigninManager is responsible for dealing with
114  // invalid username policy updates, we need to check this during
115  // initialization and sign the user out.
116  virtual void Initialize(Profile* profile, PrefService* local_state) OVERRIDE;
117  virtual void Shutdown() OVERRIDE;
118
119  // Invoked from an OAuthTokenFetchedCallback to complete user signin.
120  virtual void CompletePendingSignin();
121
122  // Invoked from SigninManagerAndroid to indicate that the sign-in process
123  // has completed for |username|.
124  void OnExternalSigninCompleted(const std::string& username);
125
126  // Returns true if there's a signin in progress.
127  virtual bool AuthInProgress() const OVERRIDE;
128
129  virtual bool IsSigninAllowed() const OVERRIDE;
130
131  // Returns true if the passed username is allowed by policy. Virtual for
132  // mocking in tests.
133  virtual bool IsAllowedUsername(const std::string& username) const;
134
135  // If an authentication is in progress, return the username being
136  // authenticated. Returns an empty string if no auth is in progress.
137  const std::string& GetUsernameForAuthInProgress() const;
138
139  // Handles errors if a required user info key is not returned from the
140  // GetUserInfo call.
141  void OnGetUserInfoKeyNotFound(const std::string& key);
142
143  // Set the profile preference to turn off one-click sign-in so that it won't
144  // ever show it again in this profile (even if the user tries a new account).
145  static void DisableOneClickSignIn(Profile* profile);
146
147  // GaiaAuthConsumer
148  virtual void OnClientLoginSuccess(const ClientLoginResult& result) OVERRIDE;
149  virtual void OnClientLoginFailure(
150      const GoogleServiceAuthError& error) OVERRIDE;
151  virtual void OnClientOAuthSuccess(const ClientOAuthResult& result) OVERRIDE;
152  virtual void OnClientOAuthFailure(
153      const GoogleServiceAuthError& error) OVERRIDE;
154  virtual void OnGetUserInfoSuccess(const UserInfoMap& data) OVERRIDE;
155  virtual void OnGetUserInfoFailure(
156      const GoogleServiceAuthError& error) OVERRIDE;
157
158  // content::NotificationObserver
159  virtual void Observe(int type,
160                       const content::NotificationSource& source,
161                       const content::NotificationDetails& details) OVERRIDE;
162
163  // Tells the SigninManager whether to prohibit signout for this profile.
164  // If |prohibit_signout| is true, then signout will be prohibited.
165  void ProhibitSignout(bool prohibit_signout);
166
167  // If true, signout is prohibited for this profile (calls to SignOut() are
168  // ignored).
169  bool IsSignoutProhibited() const;
170
171  // Checks if signin is allowed for the profile that owns |io_data|. This must
172  // be invoked on the IO thread, and can be used to check if signin is enabled
173  // on that thread.
174  static bool IsSigninAllowedOnIOThread(ProfileIOData* io_data);
175
176  // Allows the SigninManager to track the privileged signin process
177  // identified by |process_id| so that we can later ask (via IsSigninProcess)
178  // if it is safe to sign the user in from the current context (see
179  // OneClickSigninHelper).  All of this tracking state is reset once the
180  // renderer process terminates.
181  void SetSigninProcess(int process_id);
182  void ClearSigninProcess();
183  bool IsSigninProcess(int process_id) const;
184  bool HasSigninProcess() const;
185
186 protected:
187  // Flag saying whether signing out is allowed.
188  bool prohibit_signout_;
189
190 private:
191  enum SigninType {
192    SIGNIN_TYPE_NONE,
193    SIGNIN_TYPE_WITH_CREDENTIALS,
194    SIGNIN_TYPE_WITH_OAUTH_CODE
195  };
196
197  std::string SigninTypeToString(SigninType type);
198  friend class FakeSigninManager;
199  FRIEND_TEST_ALL_PREFIXES(SigninManagerTest, ClearTransientSigninData);
200  FRIEND_TEST_ALL_PREFIXES(SigninManagerTest, ProvideSecondFactorSuccess);
201  FRIEND_TEST_ALL_PREFIXES(SigninManagerTest, ProvideSecondFactorFailure);
202
203  // If user was signed in, load tokens from DB if available.
204  void InitTokenService();
205
206  // Called to setup the transient signin data during one of the
207  // StartSigninXXX methods.  |type| indicates which of the methods is being
208  // used to perform the signin while |username| and |password| identify the
209  // account to be signed in. Returns false and generates an auth error if the
210  // passed |username| is not allowed by policy.
211  bool PrepareForSignin(SigninType type,
212                        const std::string& username,
213                        const std::string& password);
214
215  // Called to verify GAIA cookies asynchronously before starting auto sign-in
216  // without password.
217  void VerifyGaiaCookiesBeforeSignIn(const std::string& session_index);
218
219  // Called when GAIA cookies are fetched. If LSID cookie is valid, then start
220  // auto sign-in by exchanging cookies for an oauth code.
221  void OnGaiaCookiesFetched(
222      const std::string session_index, const net::CookieList& cookie_list);
223
224  // Persists |username| as the currently signed-in account, and triggers
225  // a sign-in success notification.
226  void OnSignedIn(const std::string& username);
227
228  // Called when a new request to re-authenticate a user is in progress.
229  // Will clear in memory data but leaves the db as such so when the browser
230  // restarts we can use the old token(which might throw a password error).
231  void ClearTransientSigninData();
232
233  // Called to handle an error from a GAIA auth fetch.  Sets the last error
234  // to |error|, sends out a notification of login failure, and clears the
235  // transient signin data if |clear_transient_data| is true.
236  void HandleAuthError(const GoogleServiceAuthError& error,
237                       bool clear_transient_data);
238
239  void OnSigninAllowedPrefChanged();
240  void OnGoogleServicesUsernamePatternChanged();
241
242  // ClientLogin identity.
243  std::string possibly_invalid_username_;
244  std::string password_;  // This is kept empty whenever possible.
245  bool had_two_factor_error_;
246
247  // Result of the last client login, kept pending the lookup of the
248  // canonical email.
249  ClientLoginResult last_result_;
250
251  // Actual client login handler.
252  scoped_ptr<GaiaAuthFetcher> client_login_;
253
254  // Registrar for notifications from the TokenService.
255  content::NotificationRegistrar registrar_;
256
257  // OAuth revocation fetcher for sign outs.
258  scoped_ptr<GaiaAuthFetcher> revoke_token_fetcher_;
259
260  // Fetcher for the obfuscated user id.
261  scoped_ptr<SigninAccountIdHelper> account_id_helper_;
262
263  // The type of sign being performed.  This value is valid only between a call
264  // to one of the StartSigninXXX methods and when the sign in is either
265  // successful or not.
266  SigninType type_;
267
268  // Temporarily saves the oauth2 refresh and access tokens when signing in
269  // with credentials.  These will be passed to TokenService so that it does
270  // not need to mint new ones.
271  ClientOAuthResult temp_oauth_login_tokens_;
272
273  base::WeakPtrFactory<SigninManager> weak_pointer_factory_;
274
275  // See SetSigninProcess.  Tracks the currently active signin process
276  // by ID, if there is one.
277  int signin_process_id_;
278
279  // Callback invoked during signin after an OAuth token has been fetched
280  // but before signin is complete.
281  OAuthTokenFetchedCallback oauth_token_fetched_callback_;
282
283  scoped_ptr<SigninManagerDelegate> delegate_;
284
285  // Helper object to listen for changes to signin preferences stored in non-
286  // profile-specific local prefs (like kGoogleServicesUsernamePattern).
287  PrefChangeRegistrar local_state_pref_registrar_;
288
289  // Helper object to listen for changes to the signin allowed preference.
290  BooleanPrefMember signin_allowed_;
291
292  DISALLOW_COPY_AND_ASSIGN(SigninManager);
293};
294
295#endif  // !defined(OS_CHROMEOS)
296
297#endif  // CHROME_BROWSER_SIGNIN_SIGNIN_MANAGER_H_
298