Home | History | Annotate | Download | only in signin
      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 
     43 class CookieSettings;
     44 class GaiaAuthFetcher;
     45 class ProfileIOData;
     46 class PrefService;
     47 class SigninAccountIdHelper;
     48 class SigninGlobalError;
     49 class SigninManagerDelegate;
     50 
     51 class 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