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