• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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