Home | History | Annotate | Download | only in gaia
      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 // The TokenService will supply authentication tokens for any service that
      6 // needs it, such as sync. Whenever the user logs in, a controller watching
      7 // the token service is expected to call ClientLogin to derive a new SID and
      8 // LSID. Whenever such credentials are available, the TokenService should be
      9 // updated with new credentials. The controller should then start fetching
     10 // tokens, which will be written to the database after retrieval, as well as
     11 // provided to listeners.
     12 //
     13 // A token service controller like the ChromiumOS login is expected to:
     14 //
     15 // Initialize()  // Soon as you can
     16 // LoadTokensFromDB()  // When it's OK to talk to the database
     17 // UpdateCredentials()  // When user logs in
     18 // StartFetchingTokens()  // When it's safe to start fetching
     19 //
     20 // Typically a user of the TokenService is expected just to call:
     21 //
     22 // if (token_service.HasTokenForService(servicename)) {
     23 //   SetMyToken(token_service.GetTokenForService(servicename));
     24 // }
     25 // RegisterSomeObserver(token_service);
     26 //
     27 // Whenever a token update occurs:
     28 // OnTokenAvailable(...) {
     29 //   if (IsServiceICareAbout(notification.service())) {
     30 //     SetMyToken(notification.token())
     31 //   }
     32 // }
     33 
     34 #ifndef CHROME_BROWSER_NET_GAIA_TOKEN_SERVICE_H_
     35 #define CHROME_BROWSER_NET_GAIA_TOKEN_SERVICE_H_
     36 #pragma once
     37 
     38 #include <map>
     39 #include <string>
     40 
     41 #include "base/gtest_prod_util.h"
     42 #include "base/memory/scoped_ptr.h"
     43 #include "chrome/browser/webdata/web_data_service.h"
     44 #include "chrome/common/net/gaia/gaia_auth_consumer.h"
     45 #include "chrome/common/net/gaia/gaia_auth_fetcher.h"
     46 #include "chrome/common/net/gaia/google_service_auth_error.h"
     47 #include "content/common/notification_observer.h"
     48 #include "content/common/notification_registrar.h"
     49 
     50 class Profile;
     51 
     52 namespace net {
     53 class URLRequestContextGetter;
     54 }
     55 
     56 // The TokenService is a Profile member, so all calls are expected
     57 // from the UI thread.
     58 class TokenService : public GaiaAuthConsumer,
     59                      public WebDataServiceConsumer,
     60                      public NotificationObserver {
     61  public:
     62    TokenService();
     63    virtual ~TokenService();
     64 
     65   // Notification classes
     66   class TokenAvailableDetails {
     67    public:
     68     TokenAvailableDetails() {}
     69     TokenAvailableDetails(const std::string& service,
     70                           const std::string& token)
     71         : service_(service), token_(token) {}
     72     const std::string& service() const { return service_; }
     73     const std::string& token() const { return token_; }
     74    private:
     75     std::string service_;
     76     std::string token_;
     77   };
     78 
     79   class TokenRequestFailedDetails {
     80    public:
     81     TokenRequestFailedDetails()
     82         : error_(GoogleServiceAuthError::NONE) {}
     83     TokenRequestFailedDetails(const std::string& service,
     84                               const GoogleServiceAuthError& error)
     85         : service_(service), error_(error) {}
     86     const std::string& service() const { return service_; }
     87     const GoogleServiceAuthError& error() const { return error_; }
     88    private:
     89     std::string service_;
     90     GoogleServiceAuthError error_;
     91   };
     92 
     93   // Initialize this token service with a request source
     94   // (usually from a GaiaAuthConsumer constant), and the profile.
     95   // Typically you'd then update the credentials.
     96   void Initialize(const char* const source, Profile* profile);
     97 
     98   // Update the credentials in the token service.
     99   // Afterwards you can StartFetchingTokens.
    100   void UpdateCredentials(
    101       const GaiaAuthConsumer::ClientLoginResult& credentials);
    102 
    103   // Terminate any running requests and reset the TokenService to a clean
    104   // slate. Resets in memory structures. Does not modify the DB.
    105   // When this is done, no tokens will be left in memory and no
    106   // user credentials will be left. Useful if a user is logging out.
    107   // Initialize doesn't need to be called again but UpdateCredentials does.
    108   void ResetCredentialsInMemory();
    109 
    110   // Async load all tokens for services we know of from the DB.
    111   // You should do this at startup. Optionally you can do it again
    112   // after you reset in memory credentials.
    113   void LoadTokensFromDB();
    114 
    115   // Clear all DB stored tokens for the current profile. Tokens may still be
    116   // available in memory. If a DB load is pending it may still be serviced.
    117   void EraseTokensFromDB();
    118 
    119   // For legacy services with their own auth routines, they can just read
    120   // the LSID out directly. Deprecated.
    121   bool HasLsid() const;
    122   const std::string& GetLsid() const;
    123   // Did we get a proper LSID?
    124   bool AreCredentialsValid() const;
    125 
    126   // Tokens will be fetched for all services(sync, talk) in the background.
    127   // Results come back via event channel. Services can also poll before events
    128   // are issued.
    129   void StartFetchingTokens();
    130   bool HasTokenForService(const char* const service) const;
    131   const std::string& GetTokenForService(const char* const service) const;
    132 
    133   // For tests only. Doesn't save to the WebDB.
    134   void IssueAuthTokenForTest(const std::string& service,
    135                              const std::string& auth_token);
    136 
    137   // GaiaAuthConsumer implementation.
    138   virtual void OnIssueAuthTokenSuccess(const std::string& service,
    139                                        const std::string& auth_token);
    140   virtual void OnIssueAuthTokenFailure(const std::string& service,
    141                                        const GoogleServiceAuthError& error);
    142 
    143   // WebDataServiceConsumer implementation.
    144   virtual void OnWebDataServiceRequestDone(WebDataService::Handle h,
    145                                            const WDTypedResult* result);
    146 
    147   // NotificationObserver implementation.
    148   virtual void Observe(NotificationType type,
    149                        const NotificationSource& source,
    150                        const NotificationDetails& details);
    151 
    152  private:
    153 
    154   void FireTokenAvailableNotification(const std::string& service,
    155                                       const std::string& auth_token);
    156 
    157   void FireTokenRequestFailedNotification(const std::string& service,
    158                                           const GoogleServiceAuthError& error);
    159 
    160   void LoadTokensIntoMemory(const std::map<std::string, std::string>& in_toks,
    161                             std::map<std::string, std::string>* out_toks);
    162 
    163   void SaveAuthTokenToDB(const std::string& service,
    164                          const std::string& auth_token);
    165 
    166   // Web data service to access tokens from.
    167   scoped_refptr<WebDataService> web_data_service_;
    168   // Getter to use for fetchers.
    169   scoped_refptr<net::URLRequestContextGetter> getter_;
    170   // Request handle to load Gaia tokens from DB.
    171   WebDataService::Handle token_loading_query_;
    172 
    173   // Gaia request source for Gaia accounting.
    174   std::string source_;
    175   // Credentials from ClientLogin for Issuing auth tokens.
    176   GaiaAuthConsumer::ClientLoginResult credentials_;
    177 
    178   // Size of array of services (must be defined here).
    179   static const int kNumServices = 4;
    180   // List of services that we're performing operations for.
    181   static const char* kServices[kNumServices];
    182   // A bunch of fetchers suitable for token issuing. We don't care about
    183   // the ordering, nor do we care which is for which service.
    184   scoped_ptr<GaiaAuthFetcher> fetchers_[kNumServices];
    185   // Map from service to token.
    186   std::map<std::string, std::string> token_map_;
    187 
    188   NotificationRegistrar registrar_;
    189 
    190   FRIEND_TEST_ALL_PREFIXES(TokenServiceTest, LoadTokensIntoMemoryBasic);
    191   FRIEND_TEST_ALL_PREFIXES(TokenServiceTest, LoadTokensIntoMemoryAdvanced);
    192 
    193   DISALLOW_COPY_AND_ASSIGN(TokenService);
    194 };
    195 
    196 #endif  // CHROME_BROWSER_NET_GAIA_TOKEN_SERVICE_H_
    197