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: TokenAvailableDetails()68 TokenAvailableDetails() {} TokenAvailableDetails(const std::string & service,const std::string & token)69 TokenAvailableDetails(const std::string& service, 70 const std::string& token) 71 : service_(service), token_(token) {} service()72 const std::string& service() const { return service_; } token()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: TokenRequestFailedDetails()81 TokenRequestFailedDetails() 82 : error_(GoogleServiceAuthError::NONE) {} TokenRequestFailedDetails(const std::string & service,const GoogleServiceAuthError & error)83 TokenRequestFailedDetails(const std::string& service, 84 const GoogleServiceAuthError& error) 85 : service_(service), error_(error) {} service()86 const std::string& service() const { return service_; } error()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