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