Switch Android ProfileSyncService to OAuth2
[chromium-blink-merge.git] / chrome / browser / signin / oauth2_token_service.h
blobf96150548bffcb3b66d2b4033037e25d3075df29
1 // Copyright 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.
5 #ifndef CHROME_BROWSER_SIGNIN_OAUTH2_TOKEN_SERVICE_H_
6 #define CHROME_BROWSER_SIGNIN_OAUTH2_TOKEN_SERVICE_H_
8 #include <map>
9 #include <set>
10 #include <string>
12 #include "base/basictypes.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/observer_list.h"
17 #include "base/time/time.h"
18 #include "google_apis/gaia/google_service_auth_error.h"
20 namespace base {
21 class Time;
24 namespace net {
25 class URLRequestContextGetter;
28 class GoogleServiceAuthError;
30 // Abstract base class for a service that fetches and caches OAuth2 access
31 // tokens. Concrete subclasses should implement GetRefreshToken to return
32 // the appropriate refresh token.
34 // All calls are expected from the UI thread.
36 // To use this service, call StartRequest() with a given set of scopes and a
37 // consumer of the request results. The consumer is required to outlive the
38 // request. The request can be deleted. The consumer may be called back
39 // asynchronously with the fetch results.
41 // - If the consumer is not called back before the request is deleted, it will
42 // never be called back.
43 // Note in this case, the actual network requests are not canceled and the
44 // cache will be populated with the fetched results; it is just the consumer
45 // callback that is aborted.
47 // - Otherwise the consumer will be called back with the request and the fetch
48 // results.
50 // The caller of StartRequest() owns the returned request and is responsible to
51 // delete the request even once the callback has been invoked.
52 class OAuth2TokenService {
53 public:
54 // Class representing a request that fetches an OAuth2 access token.
55 class Request {
56 public:
57 virtual ~Request();
58 protected:
59 Request();
62 // Class representing the consumer of a Request passed to |StartRequest|,
63 // which will be called back when the request completes.
64 class Consumer {
65 public:
66 Consumer();
67 virtual ~Consumer();
68 // |request| is a Request that is started by this consumer and has
69 // completed.
70 virtual void OnGetTokenSuccess(const Request* request,
71 const std::string& access_token,
72 const base::Time& expiration_time) = 0;
73 virtual void OnGetTokenFailure(const Request* request,
74 const GoogleServiceAuthError& error) = 0;
77 // Classes that want to listen for token availability should implement this
78 // interface and register with the AddObserver() call.
79 // TODO(rogerta): may get rid of |error| argument for OnRefreshTokenRevoked()
80 // once we stop supporting ClientLogin. Need to evaluate if its still useful.
81 class Observer {
82 public:
83 // Called whenever a new login-scoped refresh token is available for
84 // account |account_id|. Once available, access tokens can be retrieved for
85 // this account. This is called during initial startup for each token
86 // loaded.
87 virtual void OnRefreshTokenAvailable(const std::string& account_id) {}
88 // Called whenever the login-scoped refresh token becomes unavailable for
89 // account |account_id|.
90 virtual void OnRefreshTokenRevoked(const std::string& account_id,
91 const GoogleServiceAuthError& error) {}
92 // Called after all refresh tokens are loaded during OAuth2TokenService
93 // startup.
94 virtual void OnRefreshTokensLoaded() {}
95 // Called after all refresh tokens are removed from OAuth2TokenService.
96 virtual void OnRefreshTokensCleared() {}
97 protected:
98 virtual ~Observer() {}
101 // A set of scopes in OAuth2 authentication.
102 typedef std::set<std::string> ScopeSet;
104 explicit OAuth2TokenService(net::URLRequestContextGetter* getter);
105 virtual ~OAuth2TokenService();
107 // Add or remove observers of this token service.
108 void AddObserver(Observer* observer);
109 void RemoveObserver(Observer* observer);
111 // Checks in the cache for a valid access token, and if not found starts
112 // a request for an OAuth2 access token using the OAuth2 refresh token
113 // maintained by this instance. The caller owns the returned Request.
114 // |scopes| is the set of scopes to get an access token for, |consumer| is
115 // the object that will be called back with results if the returned request
116 // is not deleted.
117 virtual scoped_ptr<Request> StartRequest(const ScopeSet& scopes,
118 Consumer* consumer);
120 // Returns true if a refresh token exists. If false, calls to
121 // |StartRequest| will result in a Consumer::OnGetTokenFailure callback.
122 virtual bool RefreshTokenIsAvailable();
124 // Mark an OAuth2 access token as invalid. This should be done if the token
125 // was received from this class, but was not accepted by the server (e.g.,
126 // the server returned 401 Unauthorized). The token will be removed from the
127 // cache for the given scopes.
128 virtual void InvalidateToken(const ScopeSet& scopes,
129 const std::string& invalid_token);
131 // Return the current number of entries in the cache.
132 int cache_size_for_testing() const;
133 void set_max_authorization_token_fetch_retries_for_testing(int max_retries);
135 protected:
136 // Implements a cancelable |OAuth2TokenService::Request|, which should be
137 // operated on the UI thread.
138 // TODO(davidroche): move this out of header file.
139 class RequestImpl : public base::SupportsWeakPtr<RequestImpl>,
140 public Request {
141 public:
142 // |consumer| is required to outlive this.
143 explicit RequestImpl(Consumer* consumer);
144 virtual ~RequestImpl();
146 // Informs |consumer_| that this request is completed.
147 void InformConsumer(const GoogleServiceAuthError& error,
148 const std::string& access_token,
149 const base::Time& expiration_date);
151 private:
152 // |consumer_| to call back when this request completes.
153 Consumer* const consumer_;
156 // Subclasses should return the refresh token maintained.
157 // If no token is available, return an empty string.
158 virtual std::string GetRefreshToken() = 0;
160 // Subclasses can override if they want to report errors to the user.
161 virtual void UpdateAuthError(const GoogleServiceAuthError& error);
163 // Add a new entry to the cache.
164 // Subclasses can override if there are implementation-specific reasons
165 // that an access token should ever not be cached.
166 virtual void RegisterCacheEntry(const std::string& refresh_token,
167 const ScopeSet& scopes,
168 const std::string& access_token,
169 const base::Time& expiration_date);
171 // Returns true if GetCacheEntry would return a valid cache entry for the
172 // given scopes.
173 bool HasCacheEntry(const ScopeSet& scopes);
175 // Posts a task to fire the Consumer callback with the cached token. Must
176 // Must only be called if HasCacheEntry() returns true.
177 scoped_ptr<Request> StartCacheLookupRequest(const ScopeSet& scopes,
178 Consumer* consumer);
180 // Clears the internal token cache.
181 void ClearCache();
183 // Called by subclasses to notify observers.
184 void FireRefreshTokenAvailable(const std::string& account_id);
185 void FireRefreshTokenRevoked(const std::string& account_id,
186 const GoogleServiceAuthError& error);
187 void FireRefreshTokensLoaded();
188 void FireRefreshTokensCleared();
190 private:
191 // Class that fetches an OAuth2 access token for a given set of scopes and
192 // OAuth2 refresh token.
193 class Fetcher;
194 friend class Fetcher;
196 // Struct that contains the information of an OAuth2 access token.
197 struct CacheEntry {
198 std::string access_token;
199 base::Time expiration_date;
202 // Returns a currently valid OAuth2 access token for the given set of scopes,
203 // or NULL if none have been cached. Note the user of this method should
204 // ensure no entry with the same |scopes| is added before the usage of the
205 // returned entry is done.
206 const CacheEntry* GetCacheEntry(const ScopeSet& scopes);
209 // Removes an access token for the given set of scopes from the cache.
210 // Returns true if the entry was removed, otherwise false.
211 bool RemoveCacheEntry(const OAuth2TokenService::ScopeSet& scopes,
212 const std::string& token_to_remove);
215 // Called when |fetcher| finishes fetching.
216 void OnFetchComplete(Fetcher* fetcher);
218 // Getter to use for fetchers.
219 scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
221 // The cache of currently valid tokens.
222 typedef std::map<ScopeSet, CacheEntry> TokenCache;
223 TokenCache token_cache_;
225 // The parameters (refresh token and scope set) used to fetch an OAuth2 access
226 // token.
227 typedef std::pair<std::string, ScopeSet> FetchParameters;
228 // A map from fetch parameters to a fetcher that is fetching an OAuth2 access
229 // token using these parameters.
230 std::map<FetchParameters, Fetcher*> pending_fetchers_;
232 // List of observers to notify when token availiability changes.
233 // Makes sure list is empty on destruction.
234 ObserverList<Observer, true> observer_list_;
236 // Maximum number of retries in fetching an OAuth2 access token.
237 static int max_fetch_retry_num_;
239 DISALLOW_COPY_AND_ASSIGN(OAuth2TokenService);
242 #endif // CHROME_BROWSER_SIGNIN_OAUTH2_TOKEN_SERVICE_H_