| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // The TokenService will supply authentication tokens for any service that |
| // needs it, such as sync. Whenever the user logs in, a controller watching |
| // the token service is expected to call ClientLogin to derive a new SID and |
| // LSID. Whenever such credentials are available, the TokenService should be |
| // updated with new credentials. The controller should then start fetching |
| // tokens, which will be written to the database after retrieval, as well as |
| // provided to listeners. |
| // |
| // A token service controller like the ChromiumOS login is expected to: |
| // |
| // Initialize() // Soon as you can |
| // LoadTokensFromDB() // When it's OK to talk to the database |
| // UpdateCredentials() // When user logs in |
| // StartFetchingTokens() // When it's safe to start fetching |
| // |
| // Typically a user of the TokenService is expected just to call: |
| // |
| // if (token_service.HasTokenForService(servicename)) { |
| // SetMyToken(token_service.GetTokenForService(servicename)); |
| // } |
| // RegisterSomeObserver(token_service); |
| // |
| // Whenever a token update occurs: |
| // OnTokenAvailable(...) { |
| // if (IsServiceICareAbout(notification.service())) { |
| // SetMyToken(notification.token()) |
| // } |
| // } |
| |
| #ifndef CHROME_BROWSER_NET_GAIA_TOKEN_SERVICE_H_ |
| #define CHROME_BROWSER_NET_GAIA_TOKEN_SERVICE_H_ |
| #pragma once |
| |
| #include <map> |
| #include <string> |
| |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "chrome/browser/webdata/web_data_service.h" |
| #include "chrome/common/net/gaia/gaia_auth_consumer.h" |
| #include "chrome/common/net/gaia/gaia_auth_fetcher.h" |
| #include "chrome/common/net/gaia/google_service_auth_error.h" |
| #include "content/common/notification_observer.h" |
| #include "content/common/notification_registrar.h" |
| |
| class URLRequestContextGetter; |
| class Profile; |
| |
| // The TokenService is a Profile member, so all calls are expected |
| // from the UI thread. |
| class TokenService : public GaiaAuthConsumer, |
| public WebDataServiceConsumer, |
| public NotificationObserver { |
| public: |
| TokenService(); |
| virtual ~TokenService(); |
| |
| // Notification classes |
| class TokenAvailableDetails { |
| public: |
| TokenAvailableDetails() {} |
| TokenAvailableDetails(const std::string& service, |
| const std::string& token) |
| : service_(service), token_(token) {} |
| const std::string& service() const { return service_; } |
| const std::string& token() const { return token_; } |
| private: |
| std::string service_; |
| std::string token_; |
| }; |
| |
| class TokenRequestFailedDetails { |
| public: |
| TokenRequestFailedDetails() |
| : error_(GoogleServiceAuthError::NONE) {} |
| TokenRequestFailedDetails(const std::string& service, |
| const GoogleServiceAuthError& error) |
| : service_(service), error_(error) {} |
| const std::string& service() const { return service_; } |
| const GoogleServiceAuthError& error() const { return error_; } |
| private: |
| std::string service_; |
| GoogleServiceAuthError error_; |
| }; |
| |
| // Initialize this token service with a request source |
| // (usually from a GaiaAuthConsumer constant), and the profile. |
| // Typically you'd then update the credentials. |
| void Initialize(const char* const source, Profile* profile); |
| |
| // Update the credentials in the token service. |
| // Afterwards you can StartFetchingTokens. |
| void UpdateCredentials( |
| const GaiaAuthConsumer::ClientLoginResult& credentials); |
| |
| // Terminate any running requests and reset the TokenService to a clean |
| // slate. Resets in memory structures. Does not modify the DB. |
| // When this is done, no tokens will be left in memory and no |
| // user credentials will be left. Useful if a user is logging out. |
| // Initialize doesn't need to be called again but UpdateCredentials does. |
| void ResetCredentialsInMemory(); |
| |
| // Async load all tokens for services we know of from the DB. |
| // You should do this at startup. Optionally you can do it again |
| // after you reset in memory credentials. |
| void LoadTokensFromDB(); |
| |
| // Clear all DB stored tokens for the current profile. Tokens may still be |
| // available in memory. If a DB load is pending it may still be serviced. |
| void EraseTokensFromDB(); |
| |
| // For legacy services with their own auth routines, they can just read |
| // the LSID out directly. Deprecated. |
| bool HasLsid() const; |
| const std::string& GetLsid() const; |
| // Did we get a proper LSID? |
| bool AreCredentialsValid() const; |
| |
| // Tokens will be fetched for all services(sync, talk) in the background. |
| // Results come back via event channel. Services can also poll before events |
| // are issued. |
| void StartFetchingTokens(); |
| bool HasTokenForService(const char* const service) const; |
| const std::string& GetTokenForService(const char* const service) const; |
| |
| // For tests only. Doesn't save to the WebDB. |
| void IssueAuthTokenForTest(const std::string& service, |
| const std::string& auth_token); |
| |
| // GaiaAuthConsumer implementation. |
| virtual void OnIssueAuthTokenSuccess(const std::string& service, |
| const std::string& auth_token); |
| virtual void OnIssueAuthTokenFailure(const std::string& service, |
| const GoogleServiceAuthError& error); |
| |
| // WebDataServiceConsumer implementation. |
| virtual void OnWebDataServiceRequestDone(WebDataService::Handle h, |
| const WDTypedResult* result); |
| |
| // NotificationObserver implementation. |
| virtual void Observe(NotificationType type, |
| const NotificationSource& source, |
| const NotificationDetails& details); |
| |
| private: |
| |
| void FireTokenAvailableNotification(const std::string& service, |
| const std::string& auth_token); |
| |
| void FireTokenRequestFailedNotification(const std::string& service, |
| const GoogleServiceAuthError& error); |
| |
| void LoadTokensIntoMemory(const std::map<std::string, std::string>& in_toks, |
| std::map<std::string, std::string>* out_toks); |
| |
| void SaveAuthTokenToDB(const std::string& service, |
| const std::string& auth_token); |
| |
| // Web data service to access tokens from. |
| scoped_refptr<WebDataService> web_data_service_; |
| // Getter to use for fetchers. |
| scoped_refptr<URLRequestContextGetter> getter_; |
| // Request handle to load Gaia tokens from DB. |
| WebDataService::Handle token_loading_query_; |
| |
| // Gaia request source for Gaia accounting. |
| std::string source_; |
| // Credentials from ClientLogin for Issuing auth tokens. |
| GaiaAuthConsumer::ClientLoginResult credentials_; |
| |
| // Size of array of services (must be defined here). |
| static const int kNumServices = 4; |
| // List of services that we're performing operations for. |
| static const char* kServices[kNumServices]; |
| // A bunch of fetchers suitable for token issuing. We don't care about |
| // the ordering, nor do we care which is for which service. |
| scoped_ptr<GaiaAuthFetcher> fetchers_[kNumServices]; |
| // Map from service to token. |
| std::map<std::string, std::string> token_map_; |
| |
| NotificationRegistrar registrar_; |
| |
| FRIEND_TEST_ALL_PREFIXES(TokenServiceTest, LoadTokensIntoMemoryBasic); |
| FRIEND_TEST_ALL_PREFIXES(TokenServiceTest, LoadTokensIntoMemoryAdvanced); |
| |
| DISALLOW_COPY_AND_ASSIGN(TokenService); |
| }; |
| |
| #endif // CHROME_BROWSER_NET_GAIA_TOKEN_SERVICE_H_ |