OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "google_apis/gaia/oauth2_token_service.h" | 5 #include "google_apis/gaia/oauth2_token_service.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/memory/weak_ptr.h" | 10 #include "base/memory/weak_ptr.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "base/rand_util.h" | 12 #include "base/rand_util.h" |
13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
14 #include "base/time/time.h" | 14 #include "base/time/time.h" |
15 #include "base/timer/timer.h" | 15 #include "base/timer/timer.h" |
16 #include "google_apis/gaia/gaia_urls.h" | 16 #include "google_apis/gaia/gaia_urls.h" |
17 #include "google_apis/gaia/google_service_auth_error.h" | 17 #include "google_apis/gaia/google_service_auth_error.h" |
| 18 #include "google_apis/gaia/oauth2_access_token_consumer.h" |
| 19 #include "google_apis/gaia/oauth2_access_token_fetcher.h" |
18 #include "net/url_request/url_request_context_getter.h" | 20 #include "net/url_request/url_request_context_getter.h" |
19 | 21 |
20 int OAuth2TokenService::max_fetch_retry_num_ = 5; | 22 int OAuth2TokenService::max_fetch_retry_num_ = 5; |
21 | 23 |
22 OAuth2TokenService::ClientScopeSet::ClientScopeSet( | |
23 const std::string& client_id, | |
24 const ScopeSet& scopes) | |
25 : client_id(client_id), | |
26 scopes(scopes) { | |
27 } | |
28 | |
29 OAuth2TokenService::ClientScopeSet::~ClientScopeSet() { | |
30 } | |
31 | |
32 bool OAuth2TokenService::ClientScopeSet::operator<( | |
33 const ClientScopeSet& s) const { | |
34 if (client_id < s.client_id) | |
35 return true; | |
36 else if (s.client_id < client_id) | |
37 return false; | |
38 | |
39 return scopes < s.scopes; | |
40 } | |
41 | |
42 OAuth2TokenService::FetchParameters::FetchParameters( | |
43 const std::string& client_id, | |
44 const std::string& refresh_token, | |
45 const ScopeSet& scopes) | |
46 : client_id(client_id), | |
47 refresh_token(refresh_token), | |
48 scopes(scopes) { | |
49 } | |
50 | |
51 OAuth2TokenService::FetchParameters::~FetchParameters() { | |
52 } | |
53 | |
54 bool OAuth2TokenService::FetchParameters::operator<( | |
55 const FetchParameters& p) const { | |
56 if (client_id < p.client_id) | |
57 return true; | |
58 else if (p.client_id < client_id) | |
59 return false; | |
60 | |
61 if (refresh_token < p.refresh_token) | |
62 return true; | |
63 else if (p.refresh_token < refresh_token) | |
64 return false; | |
65 | |
66 return scopes < p.scopes; | |
67 } | |
68 | |
69 OAuth2TokenService::RequestImpl::RequestImpl( | 24 OAuth2TokenService::RequestImpl::RequestImpl( |
70 OAuth2TokenService::Consumer* consumer) | 25 OAuth2TokenService::Consumer* consumer) |
71 : consumer_(consumer) { | 26 : consumer_(consumer) { |
72 } | 27 } |
73 | 28 |
74 OAuth2TokenService::RequestImpl::~RequestImpl() { | 29 OAuth2TokenService::RequestImpl::~RequestImpl() { |
75 DCHECK(CalledOnValidThread()); | 30 DCHECK(CalledOnValidThread()); |
76 } | 31 } |
77 | 32 |
78 void OAuth2TokenService::RequestImpl::InformConsumer( | 33 void OAuth2TokenService::RequestImpl::InformConsumer( |
79 const GoogleServiceAuthError& error, | 34 const GoogleServiceAuthError& error, |
80 const std::string& access_token, | 35 const std::string& access_token, |
81 const base::Time& expiration_date) { | 36 const base::Time& expiration_date) { |
82 DCHECK(CalledOnValidThread()); | 37 DCHECK(CalledOnValidThread()); |
83 if (error.state() == GoogleServiceAuthError::NONE) | 38 if (error.state() == GoogleServiceAuthError::NONE) |
84 consumer_->OnGetTokenSuccess(this, access_token, expiration_date); | 39 consumer_->OnGetTokenSuccess(this, access_token, expiration_date); |
85 else | 40 else |
86 consumer_->OnGetTokenFailure(this, error); | 41 consumer_->OnGetTokenFailure(this, error); |
87 } | 42 } |
88 | 43 |
89 // Class that fetches an OAuth2 access token for a given set of scopes and | |
90 // OAuth2 refresh token. | |
91 | |
92 // Class that fetches OAuth2 access tokens for given scopes and refresh token. | 44 // Class that fetches OAuth2 access tokens for given scopes and refresh token. |
93 // | 45 // |
94 // It aims to meet OAuth2TokenService's requirements on token fetching. Retry | 46 // It aims to meet OAuth2TokenService's requirements on token fetching. Retry |
95 // mechanism is used to handle failures. | 47 // mechanism is used to handle failures. |
96 // | 48 // |
97 // To use this class, call CreateAndStart() to create and start a Fetcher. | 49 // To use this class, call CreateAndStart() to create and start a Fetcher. |
98 // | 50 // |
99 // The Fetcher will call back the service by calling | 51 // The Fetcher will call back the service by calling |
100 // OAuth2TokenService::OnFetchComplete() when it completes fetching, if it is | 52 // OAuth2TokenService::OnFetchComplete() when it completes fetching, if it is |
101 // not destructed before it completes fetching; if the Fetcher is destructed | 53 // not destructed before it completes fetching; if the Fetcher is destructed |
102 // before it completes fetching, the service will never be called back. The | 54 // before it completes fetching, the service will never be called back. The |
103 // Fetcher destructs itself after calling back the service when finishes | 55 // Fetcher destructs itself after calling back the service when finishes |
104 // fetching. | 56 // fetching. |
105 // | 57 // |
106 // Requests that are waiting for the fetching results of this Fetcher can be | 58 // Requests that are waiting for the fetching results of this Fetcher can be |
107 // added to the Fetcher by calling | 59 // added to the Fetcher by calling |
108 // OAuth2TokenService::Fetcher::AddWaitingRequest() before the Fetcher | 60 // OAuth2TokenService::Fetcher::AddWaitingRequest() before the Fetcher completes |
109 // completes fetching. | 61 // fetching. |
110 // | 62 // |
111 // The waiting requests are taken as weak pointers and they can be deleted. | 63 // The waiting requests are taken as weak pointers and they can be deleted. The |
112 // The waiting requests will be called back with fetching results if they are | 64 // waiting requests will be called back with fetching results if they are not |
113 // not deleted | 65 // deleted |
114 // - when the Fetcher completes fetching, if the Fetcher is not destructed | 66 // - when the Fetcher completes fetching, if the Fetcher is not destructed |
115 // before it completes fetching, or | 67 // before it completes fetching, or |
116 // - when the Fetcher is destructed if the Fetcher is destructed before it | 68 // - when the Fetcher is destructed if the Fetcher is destructed before it |
117 // completes fetching (in this case, the waiting requests will be called | 69 // completes fetching (in this case, the waiting requests will be called back |
118 // back with error). | 70 // with error). |
119 class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { | 71 class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { |
120 public: | 72 public: |
121 // Creates a Fetcher and starts fetching an OAuth2 access token for | 73 // Creates a Fetcher and starts fetching an OAuth2 access token for |
122 // |refresh_token| and |scopes| in the request context obtained by |getter|. | 74 // |refresh_token| and |scopes| in the request context obtained by |getter|. |
123 // The given |oauth2_token_service| will be informed when fetching is done. | 75 // The given |oauth2_token_service| will be informed when fetching is done. |
124 static Fetcher* CreateAndStart(OAuth2TokenService* oauth2_token_service, | 76 static Fetcher* CreateAndStart(OAuth2TokenService* oauth2_token_service, |
125 net::URLRequestContextGetter* getter, | 77 net::URLRequestContextGetter* getter, |
126 const std::string& client_id, | 78 const std::string& chrome_client_id, |
127 const std::string& client_secret, | 79 const std::string& chrome_client_secret, |
128 const std::string& refresh_token, | 80 const std::string& refresh_token, |
129 const ScopeSet& scopes, | 81 const OAuth2TokenService::ScopeSet& scopes, |
130 base::WeakPtr<RequestImpl> waiting_request); | 82 base::WeakPtr<RequestImpl> waiting_request); |
131 virtual ~Fetcher(); | 83 virtual ~Fetcher(); |
132 | 84 |
133 // Add a request that is waiting for the result of this Fetcher. | 85 // Add a request that is waiting for the result of this Fetcher. |
134 void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request); | 86 void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request); |
135 | 87 |
136 // Returns count of waiting requests. | |
137 size_t GetWaitingRequestCount() const; | |
138 | |
139 void Cancel(); | 88 void Cancel(); |
140 | 89 |
141 const ScopeSet& GetScopeSet() const; | 90 const OAuth2TokenService::ScopeSet& GetScopeSet() const; |
142 const std::string& GetRefreshToken() const; | 91 const std::string& GetRefreshToken() const; |
143 const std::string& GetClientId() const; | |
144 | 92 |
145 // The error result from this fetcher. | 93 // The error result from this fetcher. |
146 const GoogleServiceAuthError& error() const { return error_; } | 94 const GoogleServiceAuthError& error() const { return error_; } |
147 | 95 |
148 protected: | 96 protected: |
149 // OAuth2AccessTokenConsumer | 97 // OAuth2AccessTokenConsumer |
150 virtual void OnGetTokenSuccess(const std::string& access_token, | 98 virtual void OnGetTokenSuccess(const std::string& access_token, |
151 const base::Time& expiration_date) OVERRIDE; | 99 const base::Time& expiration_date) OVERRIDE; |
152 virtual void OnGetTokenFailure( | 100 virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE; |
153 const GoogleServiceAuthError& error) OVERRIDE; | |
154 | 101 |
155 private: | 102 private: |
156 Fetcher(OAuth2TokenService* oauth2_token_service, | 103 Fetcher(OAuth2TokenService* oauth2_token_service, |
157 net::URLRequestContextGetter* getter, | 104 net::URLRequestContextGetter* getter, |
158 const std::string& client_id, | 105 const std::string& chrome_client_id, |
159 const std::string& client_secret, | 106 const std::string& chrome_client_secret, |
160 const std::string& refresh_token, | 107 const std::string& refresh_token, |
161 const OAuth2TokenService::ScopeSet& scopes, | 108 const OAuth2TokenService::ScopeSet& scopes, |
162 base::WeakPtr<RequestImpl> waiting_request); | 109 base::WeakPtr<RequestImpl> waiting_request); |
163 void Start(); | 110 void Start(); |
164 void InformWaitingRequests(); | 111 void InformWaitingRequests(); |
165 void InformWaitingRequestsAndDelete(); | 112 void InformWaitingRequestsAndDelete(); |
166 static bool ShouldRetry(const GoogleServiceAuthError& error); | 113 static bool ShouldRetry(const GoogleServiceAuthError& error); |
167 int64 ComputeExponentialBackOffMilliseconds(int retry_num); | 114 int64 ComputeExponentialBackOffMilliseconds(int retry_num); |
168 | 115 |
169 // |oauth2_token_service_| remains valid for the life of this Fetcher, since | 116 // |oauth2_token_service_| remains valid for the life of this Fetcher, since |
170 // this Fetcher is destructed in the dtor of the OAuth2TokenService or is | 117 // this Fetcher is destructed in the dtor of the OAuth2TokenService or is |
171 // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess | 118 // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess |
172 // (whichever comes first). | 119 // (whichever comes first). |
173 OAuth2TokenService* const oauth2_token_service_; | 120 OAuth2TokenService* const oauth2_token_service_; |
174 scoped_refptr<net::URLRequestContextGetter> getter_; | 121 scoped_refptr<net::URLRequestContextGetter> getter_; |
175 const std::string refresh_token_; | 122 const std::string refresh_token_; |
176 const ScopeSet scopes_; | 123 const OAuth2TokenService::ScopeSet scopes_; |
177 std::vector<base::WeakPtr<RequestImpl> > waiting_requests_; | 124 std::vector<base::WeakPtr<RequestImpl> > waiting_requests_; |
178 | 125 |
179 int retry_number_; | 126 int retry_number_; |
180 base::OneShotTimer<Fetcher> retry_timer_; | 127 base::OneShotTimer<OAuth2TokenService::Fetcher> retry_timer_; |
181 scoped_ptr<OAuth2AccessTokenFetcher> fetcher_; | 128 scoped_ptr<OAuth2AccessTokenFetcher> fetcher_; |
182 | 129 |
183 // Variables that store fetch results. | 130 // Variables that store fetch results. |
184 // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle | 131 // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle |
185 // destruction. | 132 // destruction. |
186 GoogleServiceAuthError error_; | 133 GoogleServiceAuthError error_; |
187 std::string access_token_; | 134 std::string access_token_; |
188 base::Time expiration_date_; | 135 base::Time expiration_date_; |
189 | |
190 // OAuth2 client id and secret. | 136 // OAuth2 client id and secret. |
191 std::string client_id_; | 137 std::string chrome_client_id_; |
192 std::string client_secret_; | 138 std::string chrome_client_secret_; |
193 | 139 |
194 DISALLOW_COPY_AND_ASSIGN(Fetcher); | 140 DISALLOW_COPY_AND_ASSIGN(Fetcher); |
195 }; | 141 }; |
196 | 142 |
197 // static | 143 // static |
198 OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart( | 144 OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart( |
199 OAuth2TokenService* oauth2_token_service, | 145 OAuth2TokenService* oauth2_token_service, |
200 net::URLRequestContextGetter* getter, | 146 net::URLRequestContextGetter* getter, |
201 const std::string& client_id, | 147 const std::string& chrome_client_id, |
202 const std::string& client_secret, | 148 const std::string& chrome_client_secret, |
203 const std::string& refresh_token, | 149 const std::string& refresh_token, |
204 const OAuth2TokenService::ScopeSet& scopes, | 150 const OAuth2TokenService::ScopeSet& scopes, |
205 base::WeakPtr<RequestImpl> waiting_request) { | 151 base::WeakPtr<RequestImpl> waiting_request) { |
206 OAuth2TokenService::Fetcher* fetcher = new Fetcher( | 152 OAuth2TokenService::Fetcher* fetcher = new Fetcher( |
207 oauth2_token_service, | 153 oauth2_token_service, |
208 getter, | 154 getter, |
209 client_id, | 155 chrome_client_id, |
210 client_secret, | 156 chrome_client_secret, |
211 refresh_token, | 157 refresh_token, |
212 scopes, | 158 scopes, |
213 waiting_request); | 159 waiting_request); |
214 fetcher->Start(); | 160 fetcher->Start(); |
215 return fetcher; | 161 return fetcher; |
216 } | 162 } |
217 | 163 |
218 OAuth2TokenService::Fetcher::Fetcher( | 164 OAuth2TokenService::Fetcher::Fetcher( |
219 OAuth2TokenService* oauth2_token_service, | 165 OAuth2TokenService* oauth2_token_service, |
220 net::URLRequestContextGetter* getter, | 166 net::URLRequestContextGetter* getter, |
221 const std::string& client_id, | 167 const std::string& chrome_client_id, |
222 const std::string& client_secret, | 168 const std::string& chrome_client_secret, |
223 const std::string& refresh_token, | 169 const std::string& refresh_token, |
224 const OAuth2TokenService::ScopeSet& scopes, | 170 const OAuth2TokenService::ScopeSet& scopes, |
225 base::WeakPtr<RequestImpl> waiting_request) | 171 base::WeakPtr<RequestImpl> waiting_request) |
226 : oauth2_token_service_(oauth2_token_service), | 172 : oauth2_token_service_(oauth2_token_service), |
227 getter_(getter), | 173 getter_(getter), |
228 refresh_token_(refresh_token), | 174 refresh_token_(refresh_token), |
229 scopes_(scopes), | 175 scopes_(scopes), |
230 retry_number_(0), | 176 retry_number_(0), |
231 error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE), | 177 error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE), |
232 client_id_(client_id), | 178 chrome_client_id_(chrome_client_id), |
233 client_secret_(client_secret) { | 179 chrome_client_secret_(chrome_client_secret) { |
234 DCHECK(oauth2_token_service_); | 180 DCHECK(oauth2_token_service_); |
235 DCHECK(getter_.get()); | 181 DCHECK(getter_.get()); |
236 DCHECK(refresh_token_.length()); | 182 DCHECK(refresh_token_.length()); |
237 waiting_requests_.push_back(waiting_request); | 183 waiting_requests_.push_back(waiting_request); |
238 } | 184 } |
239 | 185 |
240 OAuth2TokenService::Fetcher::~Fetcher() { | 186 OAuth2TokenService::Fetcher::~Fetcher() { |
241 // Inform the waiting requests if it has not done so. | 187 // Inform the waiting requests if it has not done so. |
242 if (waiting_requests_.size()) | 188 if (waiting_requests_.size()) |
243 InformWaitingRequests(); | 189 InformWaitingRequests(); |
244 } | 190 } |
245 | 191 |
246 void OAuth2TokenService::Fetcher::Start() { | 192 void OAuth2TokenService::Fetcher::Start() { |
247 fetcher_.reset(new OAuth2AccessTokenFetcher(this, getter_.get())); | 193 fetcher_.reset(new OAuth2AccessTokenFetcher(this, getter_.get())); |
248 fetcher_->Start(client_id_, | 194 fetcher_->Start(chrome_client_id_, |
249 client_secret_, | 195 chrome_client_secret_, |
250 refresh_token_, | 196 refresh_token_, |
251 std::vector<std::string>(scopes_.begin(), scopes_.end())); | 197 std::vector<std::string>(scopes_.begin(), scopes_.end())); |
252 retry_timer_.Stop(); | 198 retry_timer_.Stop(); |
253 } | 199 } |
254 | 200 |
255 void OAuth2TokenService::Fetcher::OnGetTokenSuccess( | 201 void OAuth2TokenService::Fetcher::OnGetTokenSuccess( |
256 const std::string& access_token, | 202 const std::string& access_token, |
257 const base::Time& expiration_date) { | 203 const base::Time& expiration_date) { |
258 fetcher_.reset(); | 204 fetcher_.reset(); |
259 | 205 |
260 // Fetch completes. | 206 // Fetch completes. |
261 error_ = GoogleServiceAuthError::AuthErrorNone(); | 207 error_ = GoogleServiceAuthError::AuthErrorNone(); |
262 access_token_ = access_token; | 208 access_token_ = access_token; |
263 expiration_date_ = expiration_date; | 209 expiration_date_ = expiration_date; |
264 | 210 |
265 // Subclasses may override this method to skip caching in some cases, but | 211 // Subclasses may override this method to skip caching in some cases, but |
266 // we still inform all waiting Consumers of a successful token fetch below. | 212 // we still inform all waiting Consumers of a successful token fetch below. |
267 // This is intentional -- some consumers may need the token for cleanup | 213 // This is intentional -- some consumers may need the token for cleanup |
268 // tasks. https://chromiumcodereview.appspot.com/11312124/ | 214 // tasks. https://chromiumcodereview.appspot.com/11312124/ |
269 oauth2_token_service_->RegisterCacheEntry(client_id_, | 215 oauth2_token_service_->RegisterCacheEntry(refresh_token_, |
270 refresh_token_, | |
271 scopes_, | 216 scopes_, |
272 access_token_, | 217 access_token_, |
273 expiration_date_); | 218 expiration_date_); |
274 InformWaitingRequestsAndDelete(); | 219 InformWaitingRequestsAndDelete(); |
275 } | 220 } |
276 | 221 |
277 void OAuth2TokenService::Fetcher::OnGetTokenFailure( | 222 void OAuth2TokenService::Fetcher::OnGetTokenFailure( |
278 const GoogleServiceAuthError& error) { | 223 const GoogleServiceAuthError& error) { |
279 fetcher_.reset(); | 224 fetcher_.reset(); |
280 | 225 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 oauth2_token_service_->OnFetchComplete(this); | 274 oauth2_token_service_->OnFetchComplete(this); |
330 InformWaitingRequests(); | 275 InformWaitingRequests(); |
331 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 276 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
332 } | 277 } |
333 | 278 |
334 void OAuth2TokenService::Fetcher::AddWaitingRequest( | 279 void OAuth2TokenService::Fetcher::AddWaitingRequest( |
335 base::WeakPtr<OAuth2TokenService::RequestImpl> waiting_request) { | 280 base::WeakPtr<OAuth2TokenService::RequestImpl> waiting_request) { |
336 waiting_requests_.push_back(waiting_request); | 281 waiting_requests_.push_back(waiting_request); |
337 } | 282 } |
338 | 283 |
339 size_t OAuth2TokenService::Fetcher::GetWaitingRequestCount() const { | |
340 return waiting_requests_.size(); | |
341 } | |
342 | |
343 void OAuth2TokenService::Fetcher::Cancel() { | 284 void OAuth2TokenService::Fetcher::Cancel() { |
344 fetcher_.reset(); | 285 fetcher_.reset(); |
345 retry_timer_.Stop(); | 286 retry_timer_.Stop(); |
346 error_ = GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED); | 287 error_ = GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED); |
347 InformWaitingRequestsAndDelete(); | 288 InformWaitingRequestsAndDelete(); |
348 } | 289 } |
349 | 290 |
350 const OAuth2TokenService::ScopeSet& OAuth2TokenService::Fetcher::GetScopeSet() | 291 const OAuth2TokenService::ScopeSet& OAuth2TokenService::Fetcher::GetScopeSet() |
351 const { | 292 const { |
352 return scopes_; | 293 return scopes_; |
353 } | 294 } |
354 | 295 |
355 const std::string& OAuth2TokenService::Fetcher::GetRefreshToken() const { | 296 const std::string& OAuth2TokenService::Fetcher::GetRefreshToken() const { |
356 return refresh_token_; | 297 return refresh_token_; |
357 } | 298 } |
358 | 299 |
359 const std::string& OAuth2TokenService::Fetcher::GetClientId() const { | |
360 return client_id_; | |
361 } | |
362 | |
363 OAuth2TokenService::Request::Request() { | 300 OAuth2TokenService::Request::Request() { |
364 } | 301 } |
365 | 302 |
366 OAuth2TokenService::Request::~Request() { | 303 OAuth2TokenService::Request::~Request() { |
367 } | 304 } |
368 | 305 |
369 OAuth2TokenService::Consumer::Consumer() { | 306 OAuth2TokenService::Consumer::Consumer() { |
370 } | 307 } |
371 | 308 |
372 OAuth2TokenService::Consumer::~Consumer() { | 309 OAuth2TokenService::Consumer::~Consumer() { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 if (!RefreshTokenIsAvailable()) { | 382 if (!RefreshTokenIsAvailable()) { |
446 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 383 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
447 &RequestImpl::InformConsumer, | 384 &RequestImpl::InformConsumer, |
448 request->AsWeakPtr(), | 385 request->AsWeakPtr(), |
449 GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP), | 386 GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP), |
450 std::string(), | 387 std::string(), |
451 base::Time())); | 388 base::Time())); |
452 return request.PassAs<Request>(); | 389 return request.PassAs<Request>(); |
453 } | 390 } |
454 | 391 |
455 ClientScopeSet client_scopes(client_id, scopes); | 392 if (HasCacheEntry(scopes)) { |
456 if (HasCacheEntry(client_scopes)) { | 393 StartCacheLookupRequest(request.get(), scopes, consumer); |
457 StartCacheLookupRequest(request.get(), client_scopes, consumer); | |
458 } else { | 394 } else { |
459 FetchOAuth2Token(request.get(), | 395 FetchOAuth2Token(request.get(), |
460 getter, | 396 getter, |
461 client_id, | 397 client_id, |
462 client_secret, | 398 client_secret, |
463 scopes); | 399 scopes); |
464 } | 400 } |
465 return request.PassAs<Request>(); | 401 return request.PassAs<Request>(); |
466 } | 402 } |
467 | 403 |
468 void OAuth2TokenService::FetchOAuth2Token(RequestImpl* request, | 404 void OAuth2TokenService::FetchOAuth2Token(RequestImpl* request, |
469 net::URLRequestContextGetter* getter, | 405 net::URLRequestContextGetter* getter, |
470 const std::string& client_id, | 406 const std::string& client_id, |
471 const std::string& client_secret, | 407 const std::string& client_secret, |
472 const ScopeSet& scopes) { | 408 const ScopeSet& scopes) { |
473 std::string refresh_token = GetRefreshToken(); | 409 std::string refresh_token = GetRefreshToken(); |
474 | 410 |
475 // If there is already a pending fetcher for |scopes| and |refresh_token|, | 411 // If there is already a pending fetcher for |scopes| and |refresh_token|, |
476 // simply register this |request| for those results rather than starting | 412 // simply register this |request| for those results rather than starting |
477 // a new fetcher. | 413 // a new fetcher. |
478 FetchParameters fetch_parameters = FetchParameters(client_id, | 414 FetchParameters fetch_parameters = std::make_pair(refresh_token, scopes); |
479 refresh_token, | |
480 scopes); | |
481 std::map<FetchParameters, Fetcher*>::iterator iter = | 415 std::map<FetchParameters, Fetcher*>::iterator iter = |
482 pending_fetchers_.find(fetch_parameters); | 416 pending_fetchers_.find(fetch_parameters); |
483 if (iter != pending_fetchers_.end()) { | 417 if (iter != pending_fetchers_.end()) { |
484 iter->second->AddWaitingRequest(request->AsWeakPtr()); | 418 iter->second->AddWaitingRequest(request->AsWeakPtr()); |
485 return; | 419 return; |
486 } | 420 } |
487 | 421 |
488 pending_fetchers_[fetch_parameters] = | 422 pending_fetchers_[fetch_parameters] = |
489 Fetcher::CreateAndStart(this, | 423 Fetcher::CreateAndStart(this, |
490 getter, | 424 getter, |
491 client_id, | 425 client_id, |
492 client_secret, | 426 client_secret, |
493 refresh_token, | 427 refresh_token, |
494 scopes, | 428 scopes, |
495 request->AsWeakPtr()); | 429 request->AsWeakPtr()); |
496 } | 430 } |
497 | 431 |
498 void OAuth2TokenService::StartCacheLookupRequest( | 432 void OAuth2TokenService::StartCacheLookupRequest( |
499 RequestImpl* request, | 433 RequestImpl* request, |
500 const OAuth2TokenService::ClientScopeSet& client_scopes, | 434 const OAuth2TokenService::ScopeSet& scopes, |
501 OAuth2TokenService::Consumer* consumer) { | 435 OAuth2TokenService::Consumer* consumer) { |
502 CHECK(HasCacheEntry(client_scopes)); | 436 CHECK(HasCacheEntry(scopes)); |
503 const CacheEntry* cache_entry = GetCacheEntry(client_scopes); | 437 const CacheEntry* cache_entry = GetCacheEntry(scopes); |
504 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 438 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
505 &RequestImpl::InformConsumer, | 439 &RequestImpl::InformConsumer, |
506 request->AsWeakPtr(), | 440 request->AsWeakPtr(), |
507 GoogleServiceAuthError(GoogleServiceAuthError::NONE), | 441 GoogleServiceAuthError(GoogleServiceAuthError::NONE), |
508 cache_entry->access_token, | 442 cache_entry->access_token, |
509 cache_entry->expiration_date)); | 443 cache_entry->expiration_date)); |
510 } | 444 } |
511 | 445 |
512 void OAuth2TokenService::InvalidateToken(const ScopeSet& scopes, | 446 void OAuth2TokenService::InvalidateToken(const ScopeSet& scopes, |
513 const std::string& invalid_token) { | 447 const std::string& invalid_token) { |
514 DCHECK(CalledOnValidThread()); | 448 DCHECK(CalledOnValidThread()); |
515 RemoveCacheEntry( | 449 RemoveCacheEntry(scopes, invalid_token); |
516 ClientScopeSet(GaiaUrls::GetInstance()->oauth2_chrome_client_id(), | |
517 scopes), | |
518 invalid_token); | |
519 } | 450 } |
520 | 451 |
521 void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) { | 452 void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) { |
522 DCHECK(CalledOnValidThread()); | 453 DCHECK(CalledOnValidThread()); |
523 | 454 |
524 // Update the auth error state so auth errors are appropriately communicated | 455 // Update the auth error state so auth errors are appropriately communicated |
525 // to the user. | 456 // to the user. |
526 UpdateAuthError(fetcher->error()); | 457 UpdateAuthError(fetcher->error()); |
527 | 458 |
528 // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh | 459 // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh |
(...skipping 16 matching lines...) Expand all Loading... |
545 // | 476 // |
546 // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its | 477 // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its |
547 // refresh token and ScopeSet. This is guaranteed by Fetcher creation in | 478 // refresh token and ScopeSet. This is guaranteed by Fetcher creation in |
548 // method StartRequest(). | 479 // method StartRequest(). |
549 // | 480 // |
550 // When this method is called, |fetcher| is alive and uncompleted. | 481 // When this method is called, |fetcher| is alive and uncompleted. |
551 // By (1), |fetcher| is created by this service. | 482 // By (1), |fetcher| is created by this service. |
552 // Then by (2), |fetcher| is recorded in |pending_fetchers_|. | 483 // Then by (2), |fetcher| is recorded in |pending_fetchers_|. |
553 // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet. | 484 // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet. |
554 std::map<FetchParameters, Fetcher*>::iterator iter = | 485 std::map<FetchParameters, Fetcher*>::iterator iter = |
555 pending_fetchers_.find(FetchParameters( | 486 pending_fetchers_.find(std::make_pair( |
556 fetcher->GetClientId(), | 487 fetcher->GetRefreshToken(), fetcher->GetScopeSet())); |
557 fetcher->GetRefreshToken(), | |
558 fetcher->GetScopeSet())); | |
559 DCHECK(iter != pending_fetchers_.end()); | 488 DCHECK(iter != pending_fetchers_.end()); |
560 DCHECK_EQ(fetcher, iter->second); | 489 DCHECK_EQ(fetcher, iter->second); |
561 pending_fetchers_.erase(iter); | 490 pending_fetchers_.erase(iter); |
562 } | 491 } |
563 | 492 |
564 bool OAuth2TokenService::HasCacheEntry( | 493 bool OAuth2TokenService::HasCacheEntry( |
565 const ClientScopeSet& client_scopes) { | 494 const OAuth2TokenService::ScopeSet& scopes) { |
566 const CacheEntry* cache_entry = GetCacheEntry(client_scopes); | 495 const CacheEntry* cache_entry = GetCacheEntry(scopes); |
567 return cache_entry && cache_entry->access_token.length(); | 496 return cache_entry && cache_entry->access_token.length(); |
568 } | 497 } |
569 | 498 |
570 const OAuth2TokenService::CacheEntry* OAuth2TokenService::GetCacheEntry( | 499 const OAuth2TokenService::CacheEntry* OAuth2TokenService::GetCacheEntry( |
571 const ClientScopeSet& client_scopes) { | 500 const OAuth2TokenService::ScopeSet& scopes) { |
572 DCHECK(CalledOnValidThread()); | 501 DCHECK(CalledOnValidThread()); |
573 TokenCache::iterator token_iterator = token_cache_.find(client_scopes); | 502 TokenCache::iterator token_iterator = token_cache_.find(scopes); |
574 if (token_iterator == token_cache_.end()) | 503 if (token_iterator == token_cache_.end()) |
575 return NULL; | 504 return NULL; |
576 if (token_iterator->second.expiration_date <= base::Time::Now()) { | 505 if (token_iterator->second.expiration_date <= base::Time::Now()) { |
577 token_cache_.erase(token_iterator); | 506 token_cache_.erase(token_iterator); |
578 return NULL; | 507 return NULL; |
579 } | 508 } |
580 return &token_iterator->second; | 509 return &token_iterator->second; |
581 } | 510 } |
582 | 511 |
583 bool OAuth2TokenService::RemoveCacheEntry( | 512 bool OAuth2TokenService::RemoveCacheEntry( |
584 const ClientScopeSet& client_scopes, | 513 const OAuth2TokenService::ScopeSet& scopes, |
585 const std::string& token_to_remove) { | 514 const std::string& token_to_remove) { |
586 DCHECK(CalledOnValidThread()); | 515 DCHECK(CalledOnValidThread()); |
587 TokenCache::iterator token_iterator = token_cache_.find(client_scopes); | 516 TokenCache::iterator token_iterator = token_cache_.find(scopes); |
588 if (token_iterator != token_cache_.end() && | 517 if (token_iterator != token_cache_.end() && |
589 token_iterator->second.access_token == token_to_remove) { | 518 token_iterator->second.access_token == token_to_remove) { |
590 token_cache_.erase(token_iterator); | 519 token_cache_.erase(token_iterator); |
591 return true; | 520 return true; |
592 } | 521 } |
593 return false; | 522 return false; |
594 } | 523 } |
595 | 524 |
596 void OAuth2TokenService::RegisterCacheEntry( | 525 void OAuth2TokenService::RegisterCacheEntry( |
597 const std::string& client_id, | |
598 const std::string& refresh_token, | 526 const std::string& refresh_token, |
599 const OAuth2TokenService::ScopeSet& scopes, | 527 const OAuth2TokenService::ScopeSet& scopes, |
600 const std::string& access_token, | 528 const std::string& access_token, |
601 const base::Time& expiration_date) { | 529 const base::Time& expiration_date) { |
602 DCHECK(CalledOnValidThread()); | 530 DCHECK(CalledOnValidThread()); |
603 | 531 |
604 CacheEntry& token = token_cache_[ClientScopeSet(client_id, | 532 CacheEntry& token = token_cache_[scopes]; |
605 scopes)]; | |
606 token.access_token = access_token; | 533 token.access_token = access_token; |
607 token.expiration_date = expiration_date; | 534 token.expiration_date = expiration_date; |
608 } | 535 } |
609 | 536 |
610 void OAuth2TokenService::UpdateAuthError(const GoogleServiceAuthError& error) { | 537 void OAuth2TokenService::UpdateAuthError(const GoogleServiceAuthError& error) { |
611 // Default implementation does nothing. | 538 // Default implementation does nothing. |
612 } | 539 } |
613 | 540 |
614 void OAuth2TokenService::ClearCache() { | 541 void OAuth2TokenService::ClearCache() { |
615 DCHECK(CalledOnValidThread()); | 542 DCHECK(CalledOnValidThread()); |
(...skipping 11 matching lines...) Expand all Loading... |
627 CancelFetchers(fetchers_to_cancel); | 554 CancelFetchers(fetchers_to_cancel); |
628 } | 555 } |
629 | 556 |
630 void OAuth2TokenService::CancelRequestsForToken( | 557 void OAuth2TokenService::CancelRequestsForToken( |
631 const std::string& refresh_token) { | 558 const std::string& refresh_token) { |
632 std::vector<Fetcher*> fetchers_to_cancel; | 559 std::vector<Fetcher*> fetchers_to_cancel; |
633 for (std::map<FetchParameters, Fetcher*>::iterator iter = | 560 for (std::map<FetchParameters, Fetcher*>::iterator iter = |
634 pending_fetchers_.begin(); | 561 pending_fetchers_.begin(); |
635 iter != pending_fetchers_.end(); | 562 iter != pending_fetchers_.end(); |
636 ++iter) { | 563 ++iter) { |
637 if (iter->first.refresh_token == refresh_token) | 564 if (iter->first.first == refresh_token) |
638 fetchers_to_cancel.push_back(iter->second); | 565 fetchers_to_cancel.push_back(iter->second); |
639 } | 566 } |
640 CancelFetchers(fetchers_to_cancel); | 567 CancelFetchers(fetchers_to_cancel); |
641 } | 568 } |
642 | 569 |
643 void OAuth2TokenService::CancelFetchers( | 570 void OAuth2TokenService::CancelFetchers( |
644 std::vector<Fetcher*> fetchers_to_cancel) { | 571 std::vector<Fetcher*> fetchers_to_cancel) { |
645 for (std::vector<OAuth2TokenService::Fetcher*>::iterator iter = | 572 for (std::vector<OAuth2TokenService::Fetcher*>::iterator iter = |
646 fetchers_to_cancel.begin(); | 573 fetchers_to_cancel.begin(); |
647 iter != fetchers_to_cancel.end(); | 574 iter != fetchers_to_cancel.end(); |
(...skipping 24 matching lines...) Expand all Loading... |
672 | 599 |
673 int OAuth2TokenService::cache_size_for_testing() const { | 600 int OAuth2TokenService::cache_size_for_testing() const { |
674 return token_cache_.size(); | 601 return token_cache_.size(); |
675 } | 602 } |
676 | 603 |
677 void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing( | 604 void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing( |
678 int max_retries) { | 605 int max_retries) { |
679 DCHECK(CalledOnValidThread()); | 606 DCHECK(CalledOnValidThread()); |
680 max_fetch_retry_num_ = max_retries; | 607 max_fetch_retry_num_ = max_retries; |
681 } | 608 } |
682 | |
683 size_t OAuth2TokenService::GetNumPendingRequestsForTesting( | |
684 const std::string& client_id, | |
685 const std::string& refresh_token, | |
686 const ScopeSet& scopes) const { | |
687 PendingFetcherMap::const_iterator iter = pending_fetchers_.find( | |
688 OAuth2TokenService::FetchParameters( | |
689 client_id, | |
690 refresh_token, | |
691 scopes)); | |
692 return iter == pending_fetchers_.end() ? | |
693 0 : iter->second->GetWaitingRequestCount(); | |
694 } | |
OLD | NEW |