- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / signin / token_service.h
1 // Copyright (c) 2012 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 either to call ClientLogin to derive a new
8 // SID and LSID, or to use GAIA OAuth requests to derive an OAuth1 access
9 // token for the OAuthLogin scope.  Whenever such credentials are available,
10 // the TokenService should be updated with new credentials.  The controller
11 // should then start fetching tokens, which will be written to the database
12 // after retrieval, as well as provided to listeners.
13 //
14 // A token service controller like the ChromiumOS login is expected to:
15 //
16 // Initialize()  // Soon as you can
17 // LoadTokensFromDB()  // When it's OK to talk to the database
18 // UpdateCredentials()  // When user logs in
19 // StartFetchingTokens()  // When it's safe to start fetching
20 //
21 // Typically a user of the TokenService is expected just to call:
22 //
23 // if (token_service.HasTokenForService(servicename)) {
24 //   SetMyToken(token_service.GetTokenForService(servicename));
25 // }
26 // RegisterSomeObserver(token_service);
27 //
28 // Whenever a token update occurs:
29 // OnTokenAvailable(...) {
30 //   if (IsServiceICareAbout(notification.service())) {
31 //     SetMyToken(notification.token())
32 //   }
33 // }
34 //
35 // There is currently no easy way to create a fake TokenService. Tests that want
36 // to use TokenService to issue tokens without the use of fake GaiaAuthFetchers
37 // or persisting the tokens to disk via WebDataService can do this by
38 // creating a TokenService (skipping the Initialize() step to avoid interacting
39 // with WebDataService) and calling IssueAuthTokenForTest() to issue new tokens.
40 // This will result in the TokenService sending out the appropriate
41 // TOKEN_AVAILABLE notification and returning the correct response to future
42 // calls to Has/GetTokenForService().
43
44 #ifndef CHROME_BROWSER_SIGNIN_TOKEN_SERVICE_H_
45 #define CHROME_BROWSER_SIGNIN_TOKEN_SERVICE_H_
46
47 #include <map>
48 #include <string>
49 #include <vector>
50
51 #include "base/gtest_prod_util.h"
52 #include "base/memory/scoped_ptr.h"
53 #include "base/observer_list.h"
54 #include "chrome/browser/signin/signin_internals_util.h"
55 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
56 #include "components/webdata/common/web_data_service_base.h"
57 #include "components/webdata/common/web_data_service_consumer.h"
58 #include "google_apis/gaia/gaia_auth_consumer.h"
59 #include "google_apis/gaia/gaia_auth_fetcher.h"
60 #include "google_apis/gaia/google_service_auth_error.h"
61
62 class Profile;
63 class TokenServiceTest;
64 class TokenWebData;
65
66 namespace net {
67 class URLRequestContextGetter;
68 }
69
70 // The TokenService is a Profile member, so all calls are expected
71 // from the UI thread.
72 class TokenService : public GaiaAuthConsumer,
73                      public BrowserContextKeyedService,
74                      public WebDataServiceConsumer {
75  public:
76    TokenService();
77    virtual ~TokenService();
78
79   // Notification classes
80   class TokenAvailableDetails {
81    public:
82     TokenAvailableDetails() {}
83     TokenAvailableDetails(const std::string& service,
84                           const std::string& token)
85         : service_(service), token_(token) {}
86     const std::string& service() const { return service_; }
87     const std::string& token() const { return token_; }
88    private:
89     std::string service_;
90     std::string token_;
91   };
92
93   class TokenRequestFailedDetails {
94    public:
95     TokenRequestFailedDetails()
96         : error_(GoogleServiceAuthError::NONE) {}
97     TokenRequestFailedDetails(const std::string& service,
98                               const GoogleServiceAuthError& error)
99         : service_(service), error_(error) {}
100     const std::string& service() const { return service_; }
101     const GoogleServiceAuthError& error() const { return error_; }
102    private:
103     std::string service_;
104     GoogleServiceAuthError error_;
105   };
106
107   // BrowserContextKeyedService implementation.
108   virtual void Shutdown() OVERRIDE;
109
110   // Methods to register or remove SigninDiagnosticObservers
111   void AddSigninDiagnosticsObserver(
112       signin_internals_util::SigninDiagnosticsObserver* observer);
113   void RemoveSigninDiagnosticsObserver(
114       signin_internals_util::SigninDiagnosticsObserver* observer);
115
116   // Initialize this token service with a request source
117   // (usually from a GaiaAuthConsumer constant), and the profile.
118   // Typically you'd then update the credentials.
119   void Initialize(const char* const source, Profile* profile);
120
121   // Used to determine whether Initialize() has been called.
122   bool Initialized() const { return !source_.empty(); }
123
124   // Add a token not supported by a fetcher.
125   void AddAuthTokenManually(const std::string& service,
126                             const std::string& auth_token);
127
128   // Update ClientLogin credentials in the token service.
129   // Afterwards you can StartFetchingTokens.
130   void UpdateCredentials(
131       const GaiaAuthConsumer::ClientLoginResult& credentials);
132
133   // Update credentials in the token service with oauth2 tokens.
134   // Afterwards you can StartFetchingTokens.
135   void UpdateCredentialsWithOAuth2(
136       const GaiaAuthConsumer::ClientOAuthResult& credentials);
137
138   // Terminate any running requests and reset the TokenService to a clean
139   // slate. Resets in memory structures. Does not modify the DB.
140   // When this is done, no tokens will be left in memory and no
141   // user credentials will be left. Useful if a user is logging out.
142   // Initialize doesn't need to be called again but UpdateCredentials does.
143   void ResetCredentialsInMemory();
144
145   // Async load all tokens for services we know of from the DB.
146   // You should do this at startup. Optionally you can do it again
147   // after you reset in memory credentials.
148   virtual void LoadTokensFromDB();
149
150   // Clear all DB stored tokens for the current profile. Tokens may still be
151   // available in memory. If a DB load is pending it may still be serviced.
152   void EraseTokensFromDB();
153
154   // Returns true if tokens have been loaded from the DB. Set when
155   // LoadTokensFromDB() completes, unset when ResetCredentialsInMemory() is
156   // called.
157   bool TokensLoadedFromDB() const;
158
159   // Returns true if the token service has either GAIA credentials or OAuth2
160   // tokens needed to fetch other service tokens.
161   virtual bool AreCredentialsValid() const;
162
163   // Tokens will be fetched for all services(sync, talk) in the background.
164   // Results come back via event channel. Services can also poll before events
165   // are issued.
166   void StartFetchingTokens();
167   virtual bool HasTokenForService(const char* service) const;
168   const std::string& GetTokenForService(const char* const service) const;
169
170   // OAuth login token is an all-powerful token that allows creating OAuth2
171   // tokens for any other scope (i.e. down-scoping).
172   // Typical use is to create an OAuth2 token for appropriate scope and then
173   // use that token to call a Google API.
174   virtual bool HasOAuthLoginToken() const;
175   virtual const std::string& GetOAuth2LoginRefreshToken() const;
176
177   // For tests only. Doesn't save to the WebDB.
178   void IssueAuthTokenForTest(const std::string& service,
179                              const std::string& auth_token);
180
181   // GaiaAuthConsumer implementation.
182   virtual void OnIssueAuthTokenSuccess(const std::string& service,
183                                        const std::string& auth_token) OVERRIDE;
184   virtual void OnIssueAuthTokenFailure(
185       const std::string& service,
186       const GoogleServiceAuthError& error) OVERRIDE;
187   virtual void OnClientOAuthSuccess(const ClientOAuthResult& result) OVERRIDE;
188   virtual void OnClientOAuthFailure(
189       const GoogleServiceAuthError& error) OVERRIDE;
190
191   // WebDataServiceConsumer implementation.
192   virtual void OnWebDataServiceRequestDone(
193       WebDataServiceBase::Handle h,
194       const WDTypedResult* result) OVERRIDE;
195
196   // Gets the list of all service names for which tokens will be retrieved.
197   static void GetServiceNames(std::vector<std::string>* names);
198
199  protected:
200   // Saves OAuth2 credentials.
201   void SaveOAuth2Credentials(const ClientOAuthResult& result);
202
203   void set_tokens_loaded(bool loaded) {
204     tokens_loaded_ = loaded;
205   }
206
207  private:
208   void FireTokenAvailableNotification(const std::string& service,
209                                       const std::string& auth_token);
210
211   void FireTokenRequestFailedNotification(const std::string& service,
212                                           const GoogleServiceAuthError& error);
213
214   void LoadTokensIntoMemory(
215       const std::map<std::string, std::string>& db_tokens,
216       std::map<std::string, std::string>* in_memory_tokens);
217   void LoadSingleTokenIntoMemory(
218       const std::map<std::string, std::string>& db_tokens,
219       std::map<std::string, std::string>* in_memory_tokens,
220       const std::string& service);
221
222   void SaveAuthTokenToDB(const std::string& service,
223                          const std::string& auth_token);
224
225   // Returns the index of the given service.
226   static int GetServiceIndex(const std::string& service);
227
228   // The profile with which this instance was initialized, or NULL.
229   Profile* profile_;
230
231   // Web data service to access tokens from.
232   scoped_refptr<TokenWebData> token_web_data_;
233   // Getter to use for fetchers.
234   scoped_refptr<net::URLRequestContextGetter> getter_;
235   // Request handle to load Gaia tokens from DB.
236   WebDataServiceBase::Handle token_loading_query_;
237   // True if token loading has completed (regardless of success).
238   bool tokens_loaded_;
239
240   // Gaia request source for Gaia accounting.
241   std::string source_;
242   // Credentials from ClientLogin for Issuing auth tokens.
243   GaiaAuthConsumer::ClientLoginResult credentials_;
244
245   // A bunch of fetchers suitable for ClientLogin token issuing. We don't care
246   // about the ordering, nor do we care which is for which service.  The
247   // number of entries in this array must match the number of entries in the
248   // kServices array declared in the cc file.  If not, a compile time error
249   // will occur.
250   scoped_ptr<GaiaAuthFetcher> fetchers_[1];
251
252   // Map from service to token.
253   std::map<std::string, std::string> token_map_;
254
255   // The list of SigninDiagnosticObservers
256   ObserverList<signin_internals_util::SigninDiagnosticsObserver>
257       signin_diagnostics_observers_;
258
259   friend class TokenServiceTest;
260   FRIEND_TEST_ALL_PREFIXES(TokenServiceTest, LoadTokensIntoMemoryBasic);
261   FRIEND_TEST_ALL_PREFIXES(TokenServiceTest, LoadTokensIntoMemoryAdvanced);
262   FRIEND_TEST_ALL_PREFIXES(TokenServiceTest, FullIntegrationNewServicesAdded);
263
264   DISALLOW_COPY_AND_ASSIGN(TokenService);
265 };
266
267 #endif  // CHROME_BROWSER_SIGNIN_TOKEN_SERVICE_H_