Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: chrome/browser/signin/oauth2_token_service.cc

Issue 12647008: Refactor OAuth2TokenService to have profile- and device-based implementations. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Moved DeviceOAuth2TokenService factory method to g_browser_process Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 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 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 "chrome/browser/signin/oauth2_token_service.h" 5 #include "chrome/browser/signin/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.h" 11 #include "base/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.h" 14 #include "base/time.h"
15 #include "base/timer.h" 15 #include "base/timer.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/signin/oauth2_token_service_factory.h"
18 #include "chrome/browser/signin/signin_manager.h"
19 #include "chrome/browser/signin/signin_manager_factory.h"
20 #include "chrome/browser/signin/token_service.h"
21 #include "chrome/browser/signin/token_service_factory.h"
22 #include "chrome/common/chrome_notification_types.h"
23 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/notification_details.h"
25 #include "content/public/browser/notification_source.h"
26 #include "google_apis/gaia/gaia_constants.h"
27 #include "google_apis/gaia/gaia_urls.h" 17 #include "google_apis/gaia/gaia_urls.h"
28 #include "google_apis/gaia/google_service_auth_error.h" 18 #include "google_apis/gaia/google_service_auth_error.h"
29 #include "google_apis/gaia/oauth2_access_token_consumer.h" 19 #include "google_apis/gaia/oauth2_access_token_consumer.h"
30 #include "google_apis/gaia/oauth2_access_token_fetcher.h" 20 #include "google_apis/gaia/oauth2_access_token_fetcher.h"
21 #include "net/url_request/url_request_context_getter.h"
31 22
32 namespace { 23 namespace {
33 24
34 // Maximum number of retries in fetching an OAuth2 access token. 25 // Maximum number of retries in fetching an OAuth2 access token.
35 const int kMaxFetchRetryNum = 5; 26 const int kMaxFetchRetryNum = 5;
36 27
37 // Returns an exponential backoff in milliseconds including randomness less than 28 // Returns an exponential backoff in milliseconds including randomness less than
38 // 1000 ms when retrying fetching an OAuth2 access token. 29 // 1000 ms when retrying fetching an OAuth2 access token.
39 int64 ComputeExponentialBackOffMilliseconds(int retry_num) { 30 int64 ComputeExponentialBackOffMilliseconds(int retry_num) {
40 DCHECK(retry_num < kMaxFetchRetryNum); 31 DCHECK(retry_num < kMaxFetchRetryNum);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 OAuth2TokenService::RequestImpl::~RequestImpl() { 65 OAuth2TokenService::RequestImpl::~RequestImpl() {
75 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 66 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
76 } 67 }
77 68
78 void OAuth2TokenService::RequestImpl::InformConsumer( 69 void OAuth2TokenService::RequestImpl::InformConsumer(
79 const GoogleServiceAuthError& error, 70 const GoogleServiceAuthError& error,
80 const std::string& access_token, 71 const std::string& access_token,
81 const base::Time& expiration_date) { 72 const base::Time& expiration_date) {
82 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 73 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
83 if (error.state() == GoogleServiceAuthError::NONE) 74 if (error.state() == GoogleServiceAuthError::NONE)
84 consumer_-> OnGetTokenSuccess(this, access_token, expiration_date); 75 consumer_->OnGetTokenSuccess(this, access_token, expiration_date);
85 else 76 else
86 consumer_-> OnGetTokenFailure(this, error); 77 consumer_->OnGetTokenFailure(this, error);
87 } 78 }
88 79
89 // Class that fetches OAuth2 access tokens for given scopes and refresh token. 80 // Class that fetches OAuth2 access tokens for given scopes and refresh token.
90 // 81 //
91 // It aims to meet OAuth2TokenService's requirements on token fetching. Retry 82 // It aims to meet OAuth2TokenService's requirements on token fetching. Retry
92 // mechanism is used to handle failures. 83 // mechanism is used to handle failures.
93 // 84 //
94 // To use this class, call CreateAndStart() to create and start a Fetcher. 85 // To use this class, call CreateAndStart() to create and start a Fetcher.
95 // 86 //
96 // The Fetcher will call back the service by calling 87 // The Fetcher will call back the service by calling
(...skipping 13 matching lines...) Expand all
110 // deleted 101 // deleted
111 // - when the Fetcher completes fetching, if the Fetcher is not destructed 102 // - when the Fetcher completes fetching, if the Fetcher is not destructed
112 // before it completes fetching, or 103 // before it completes fetching, or
113 // - when the Fetcher is destructed if the Fetcher is destructed before it 104 // - when the Fetcher is destructed if the Fetcher is destructed before it
114 // completes fetching (in this case, the waiting requests will be called back 105 // completes fetching (in this case, the waiting requests will be called back
115 // with error). 106 // with error).
116 class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { 107 class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer {
117 public: 108 public:
118 // Creates a Fetcher and starts fetching an OAuth2 access token for 109 // Creates a Fetcher and starts fetching an OAuth2 access token for
119 // |refresh_token| and |scopes| in the request context obtained by |getter|. 110 // |refresh_token| and |scopes| in the request context obtained by |getter|.
120 // |profile|'s OAuth2TokenService will be informed when fetching is done. 111 // The given |oauth2_token_service| will be informed when fetching is done.
121 static Fetcher* CreateAndStart(Profile* profile, 112 static Fetcher* CreateAndStart(OAuth2TokenService* oauth2_token_service,
122 net::URLRequestContextGetter* getter, 113 net::URLRequestContextGetter* getter,
123 const std::string& refresh_token, 114 const std::string& refresh_token,
124 const OAuth2TokenService::ScopeSet& scopes, 115 const OAuth2TokenService::ScopeSet& scopes,
125 base::WeakPtr<RequestImpl> waiting_request); 116 base::WeakPtr<RequestImpl> waiting_request);
126 virtual ~Fetcher(); 117 virtual ~Fetcher();
127 118
128 // Add a request that is waiting for the result of this Fetcher. 119 // Add a request that is waiting for the result of this Fetcher.
129 void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request); 120 void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request);
130 121
131 const OAuth2TokenService::ScopeSet& GetScopeSet() const; 122 const OAuth2TokenService::ScopeSet& GetScopeSet() const;
132 const std::string& GetRefreshToken() const; 123 const std::string& GetRefreshToken() const;
133 124
134 // The error result from this fetcher. 125 // The error result from this fetcher.
135 const GoogleServiceAuthError& error() const { return error_; } 126 const GoogleServiceAuthError& error() const { return error_; }
136 127
137 protected: 128 protected:
138 // OAuth2AccessTokenConsumer 129 // OAuth2AccessTokenConsumer
139 virtual void OnGetTokenSuccess(const std::string& access_token, 130 virtual void OnGetTokenSuccess(const std::string& access_token,
140 const base::Time& expiration_date) OVERRIDE; 131 const base::Time& expiration_date) OVERRIDE;
141 virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE; 132 virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE;
142 133
143 private: 134 private:
144 Fetcher(Profile* profile, 135 Fetcher(OAuth2TokenService* oauth2_token_service,
145 net::URLRequestContextGetter* getter, 136 net::URLRequestContextGetter* getter,
146 const std::string& refresh_token, 137 const std::string& refresh_token,
147 const OAuth2TokenService::ScopeSet& scopes, 138 const OAuth2TokenService::ScopeSet& scopes,
148 base::WeakPtr<RequestImpl> waiting_request); 139 base::WeakPtr<RequestImpl> waiting_request);
149 void Start(); 140 void Start();
150 void InformWaitingRequests(); 141 void InformWaitingRequests();
151 static bool ShouldRetry(const GoogleServiceAuthError& error); 142 static bool ShouldRetry(const GoogleServiceAuthError& error);
152 143
153 Profile* const profile_; 144 // |oauth2_token_service_| remains valid for the life of this Fetcher, since
145 // this Fetcher is destructed in the dtor of the OAuth2TokenService or is
146 // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess
147 // (whichever comes first).
148 OAuth2TokenService* const oauth2_token_service_;
154 scoped_refptr<net::URLRequestContextGetter> getter_; 149 scoped_refptr<net::URLRequestContextGetter> getter_;
155 const std::string refresh_token_; 150 const std::string refresh_token_;
156 const OAuth2TokenService::ScopeSet scopes_; 151 const OAuth2TokenService::ScopeSet scopes_;
157 std::vector<base::WeakPtr<RequestImpl> > waiting_requests_; 152 std::vector<base::WeakPtr<RequestImpl> > waiting_requests_;
158 153
159 int retry_number_; 154 int retry_number_;
160 base::OneShotTimer<OAuth2TokenService::Fetcher> retry_timer_; 155 base::OneShotTimer<OAuth2TokenService::Fetcher> retry_timer_;
161 scoped_ptr<OAuth2AccessTokenFetcher> fetcher_; 156 scoped_ptr<OAuth2AccessTokenFetcher> fetcher_;
162 157
163 // Variables that store fetch results. 158 // Variables that store fetch results.
164 // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle 159 // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle
165 // destruction. 160 // destruction.
166 GoogleServiceAuthError error_; 161 GoogleServiceAuthError error_;
167 std::string access_token_; 162 std::string access_token_;
168 base::Time expiration_date_; 163 base::Time expiration_date_;
169 164
170 DISALLOW_COPY_AND_ASSIGN(Fetcher); 165 DISALLOW_COPY_AND_ASSIGN(Fetcher);
171 }; 166 };
172 167
173 // static 168 // static
174 OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart( 169 OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart(
175 Profile* profile, 170 OAuth2TokenService* oauth2_token_service,
176 net::URLRequestContextGetter* getter, 171 net::URLRequestContextGetter* getter,
177 const std::string& refresh_token, 172 const std::string& refresh_token,
178 const OAuth2TokenService::ScopeSet& scopes, 173 const OAuth2TokenService::ScopeSet& scopes,
179 base::WeakPtr<RequestImpl> waiting_request) { 174 base::WeakPtr<RequestImpl> waiting_request) {
180 OAuth2TokenService::Fetcher* fetcher = new Fetcher( 175 OAuth2TokenService::Fetcher* fetcher = new Fetcher(
181 profile, getter, refresh_token, scopes, waiting_request); 176 oauth2_token_service, getter, refresh_token, scopes, waiting_request);
182 fetcher->Start(); 177 fetcher->Start();
183 return fetcher; 178 return fetcher;
184 } 179 }
185 180
186 OAuth2TokenService::Fetcher::Fetcher( 181 OAuth2TokenService::Fetcher::Fetcher(
187 Profile* profile, 182 OAuth2TokenService* oauth2_token_service,
188 net::URLRequestContextGetter* getter, 183 net::URLRequestContextGetter* getter,
189 const std::string& refresh_token, 184 const std::string& refresh_token,
190 const OAuth2TokenService::ScopeSet& scopes, 185 const OAuth2TokenService::ScopeSet& scopes,
191 base::WeakPtr<RequestImpl> waiting_request) 186 base::WeakPtr<RequestImpl> waiting_request)
192 : profile_(profile), 187 : oauth2_token_service_(oauth2_token_service),
193 getter_(getter), 188 getter_(getter),
194 refresh_token_(refresh_token), 189 refresh_token_(refresh_token),
195 scopes_(scopes), 190 scopes_(scopes),
196 retry_number_(0), 191 retry_number_(0),
197 error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE) { 192 error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE) {
198 DCHECK(profile_); 193 DCHECK(oauth2_token_service_);
199 DCHECK(getter_); 194 DCHECK(getter_);
200 DCHECK(refresh_token_.length()); 195 DCHECK(refresh_token_.length());
201 waiting_requests_.push_back(waiting_request); 196 waiting_requests_.push_back(waiting_request);
202 } 197 }
203 198
204 OAuth2TokenService::Fetcher::~Fetcher() { 199 OAuth2TokenService::Fetcher::~Fetcher() {
205 // Inform the waiting requests if it has not done so. 200 // Inform the waiting requests if it has not done so.
206 if (waiting_requests_.size()) 201 if (waiting_requests_.size())
207 InformWaitingRequests(); 202 InformWaitingRequests();
208 } 203 }
209 204
210 void OAuth2TokenService::Fetcher::Start() { 205 void OAuth2TokenService::Fetcher::Start() {
211 fetcher_.reset(new OAuth2AccessTokenFetcher(this, getter_)); 206 fetcher_.reset(new OAuth2AccessTokenFetcher(this, getter_));
212 fetcher_->Start(GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 207 fetcher_->Start(GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
213 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), 208 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
214 refresh_token_, 209 refresh_token_,
215 std::vector<std::string>(scopes_.begin(), scopes_.end())); 210 std::vector<std::string>(scopes_.begin(), scopes_.end()));
216 retry_timer_.Stop(); 211 retry_timer_.Stop();
217 } 212 }
218 213
219 void OAuth2TokenService::Fetcher::OnGetTokenSuccess( 214 void OAuth2TokenService::Fetcher::OnGetTokenSuccess(
220 const std::string& access_token, 215 const std::string& access_token,
221 const base::Time& expiration_date) { 216 const base::Time& expiration_date) {
222 fetcher_.reset(); 217 fetcher_.reset();
223 218
224 // Fetch completes. 219 // Fetch completes.
225 error_ = GoogleServiceAuthError(GoogleServiceAuthError::NONE); 220 error_ = GoogleServiceAuthError::AuthErrorNone();
226 access_token_ = access_token; 221 access_token_ = access_token;
227 expiration_date_ = expiration_date; 222 expiration_date_ = expiration_date;
228 223
229 // |oauth2_token_service| should not be NULL as this Fetcher is destructed in 224 // Subclasses may override this method to skip caching in some cases, but
230 // the dtor of the OAuth2TokenService that creates it if it is not scheduled 225 // we still inform all waiting Consumers of a successful token fetch below.
231 // to be destructed here and in OnGetTokenFailure(). 226 // This is intentional -- some consumers may need the token for cleanup
232 OAuth2TokenService* oauth2_token_service = 227 // tasks. https://chromiumcodereview.appspot.com/11312124/
Mattias Nissler (ping if slow) 2013/03/26 12:04:32 nit: Can we rather put the commit revision / bug n
David Roche 2013/03/27 05:09:51 I linked the code review because the comments ther
233 OAuth2TokenServiceFactory::GetForProfile(profile_); 228 oauth2_token_service_->RegisterCacheEntry(refresh_token_,
234 DCHECK(oauth2_token_service); 229 scopes_,
235 230 access_token_,
236 oauth2_token_service->RegisterCacheEntry(refresh_token_, 231 expiration_date_);
237 scopes_,
238 access_token_,
239 expiration_date_);
240 // Deregisters itself from the service to prevent more waiting requests to 232 // Deregisters itself from the service to prevent more waiting requests to
241 // be added when it calls back the waiting requests. 233 // be added when it calls back the waiting requests.
242 oauth2_token_service->OnFetchComplete(this); 234 oauth2_token_service_->OnFetchComplete(this);
243 InformWaitingRequests(); 235 InformWaitingRequests();
244 MessageLoop::current()->DeleteSoon(FROM_HERE, this); 236 MessageLoop::current()->DeleteSoon(FROM_HERE, this);
245 } 237 }
246 238
247 void OAuth2TokenService::Fetcher::OnGetTokenFailure( 239 void OAuth2TokenService::Fetcher::OnGetTokenFailure(
248 const GoogleServiceAuthError& error) { 240 const GoogleServiceAuthError& error) {
249 fetcher_.reset(); 241 fetcher_.reset();
250 242
251 if (ShouldRetry(error) && retry_number_ < kMaxFetchRetryNum) { 243 if (ShouldRetry(error) && retry_number_ < kMaxFetchRetryNum) {
252 int64 backoff = ComputeExponentialBackOffMilliseconds(retry_number_); 244 int64 backoff = ComputeExponentialBackOffMilliseconds(retry_number_);
253 ++retry_number_; 245 ++retry_number_;
254 retry_timer_.Stop(); 246 retry_timer_.Stop();
255 retry_timer_.Start(FROM_HERE, 247 retry_timer_.Start(FROM_HERE,
256 base::TimeDelta::FromMilliseconds(backoff), 248 base::TimeDelta::FromMilliseconds(backoff),
257 this, 249 this,
258 &OAuth2TokenService::Fetcher::Start); 250 &OAuth2TokenService::Fetcher::Start);
259 return; 251 return;
260 } 252 }
261 253
262 // Fetch completes. 254 // Fetch completes.
263 error_ = error; 255 error_ = error;
264 256
265 // |oauth2_token_service| should not be NULL as this Fetcher is destructed in
266 // the dtor of the OAuth2TokenService that creates it if it is not scheduled
267 // to be destructed here and in OnGetTokenSuccess().
268 OAuth2TokenService* oauth2_token_service =
269 OAuth2TokenServiceFactory::GetForProfile(profile_);
270 DCHECK(oauth2_token_service);
271 // Deregisters itself from the service to prevent more waiting requests to be 257 // Deregisters itself from the service to prevent more waiting requests to be
272 // added when it calls back the waiting requests. 258 // added when it calls back the waiting requests.
273 oauth2_token_service->OnFetchComplete(this); 259 oauth2_token_service_->OnFetchComplete(this);
274 InformWaitingRequests(); 260 InformWaitingRequests();
275 MessageLoop::current()->DeleteSoon(FROM_HERE, this); 261 MessageLoop::current()->DeleteSoon(FROM_HERE, this);
276 } 262 }
277 263
278 // static 264 // static
279 bool OAuth2TokenService::Fetcher::ShouldRetry( 265 bool OAuth2TokenService::Fetcher::ShouldRetry(
280 const GoogleServiceAuthError& error) { 266 const GoogleServiceAuthError& error) {
281 GoogleServiceAuthError::State error_state = error.state(); 267 GoogleServiceAuthError::State error_state = error.state();
282 return error_state == GoogleServiceAuthError::CONNECTION_FAILED || 268 return error_state == GoogleServiceAuthError::CONNECTION_FAILED ||
283 error_state == GoogleServiceAuthError::REQUEST_CANCELED || 269 error_state == GoogleServiceAuthError::REQUEST_CANCELED ||
(...skipping 30 matching lines...) Expand all
314 300
315 OAuth2TokenService::Request::~Request() { 301 OAuth2TokenService::Request::~Request() {
316 } 302 }
317 303
318 OAuth2TokenService::Consumer::Consumer() { 304 OAuth2TokenService::Consumer::Consumer() {
319 } 305 }
320 306
321 OAuth2TokenService::Consumer::~Consumer() { 307 OAuth2TokenService::Consumer::~Consumer() {
322 } 308 }
323 309
324 OAuth2TokenService::OAuth2TokenService() 310 OAuth2TokenService::OAuth2TokenService(net::URLRequestContextGetter* getter)
325 : profile_(NULL), 311 : request_context_getter_(getter) {
Mattias Nissler (ping if slow) 2013/03/26 12:04:32 nit: 4 space indentation
David Roche 2013/03/27 05:09:51 Done.
326 last_auth_error_(GoogleServiceAuthError::NONE) {
327 } 312 }
328 313
329 OAuth2TokenService::~OAuth2TokenService() { 314 OAuth2TokenService::~OAuth2TokenService() {
330 // Release all the pending fetchers. 315 // Release all the pending fetchers.
331 STLDeleteContainerPairSecondPointers( 316 STLDeleteContainerPairSecondPointers(
332 pending_fetchers_.begin(), pending_fetchers_.end()); 317 pending_fetchers_.begin(), pending_fetchers_.end());
333 } 318 }
334 319
335 void OAuth2TokenService::Initialize(Profile* profile) { 320 bool OAuth2TokenService::RefreshTokenIsAvailable() {
336 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 321 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
337 322 return !GetRefreshToken().empty();
338 DCHECK(profile);
339 DCHECK(!profile_);
340 profile_ = profile;
341 getter_ = profile->GetRequestContext();
342 content::Source<TokenService> token_service_source(
343 TokenServiceFactory::GetForProfile(profile));
344 registrar_.Add(this,
345 chrome::NOTIFICATION_TOKENS_CLEARED,
346 token_service_source);
347 registrar_.Add(this,
348 chrome::NOTIFICATION_TOKEN_AVAILABLE,
349 token_service_source);
350 SigninManagerFactory::GetForProfile(profile_)->signin_global_error()->
351 AddProvider(this);
352 } 323 }
353 324
354 void OAuth2TokenService::Shutdown() {
355 if (profile_) {
356 SigninManagerFactory::GetForProfile(profile_)->signin_global_error()->
357 RemoveProvider(this);
358 }
359 }
360
361
362 // static 325 // static
363 void OAuth2TokenService::InformConsumer( 326 void OAuth2TokenService::InformConsumer(
364 base::WeakPtr<OAuth2TokenService::RequestImpl> request, 327 base::WeakPtr<OAuth2TokenService::RequestImpl> request,
365 GoogleServiceAuthError error, 328 GoogleServiceAuthError error,
366 std::string access_token, 329 std::string access_token,
367 base::Time expiration_date) { 330 base::Time expiration_date) {
368 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 331 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
369 332
370 if (request) 333 if (request)
371 request->InformConsumer(error, access_token, expiration_date); 334 request->InformConsumer(error, access_token, expiration_date);
372 } 335 }
373 336
374 scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( 337 scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest(
375 const OAuth2TokenService::ScopeSet& scopes, 338 const OAuth2TokenService::ScopeSet& scopes,
376 OAuth2TokenService::Consumer* consumer) { 339 OAuth2TokenService::Consumer* consumer) {
377 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 340 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
378 341
379 scoped_ptr<RequestImpl> request(new RequestImpl(consumer)); 342 scoped_ptr<RequestImpl> request(new RequestImpl(consumer));
380 343
381 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); 344 std::string refresh_token = GetRefreshToken();
382 if (!token_service || !token_service->HasOAuthLoginToken()) { 345 if (refresh_token.empty()) {
383 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 346 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
384 &OAuth2TokenService::InformConsumer, 347 &OAuth2TokenService::InformConsumer,
385 request->AsWeakPtr(), 348 request->AsWeakPtr(),
386 GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP), 349 GoogleServiceAuthError(
350 GoogleServiceAuthError::USER_NOT_SIGNED_UP),
387 std::string(), 351 std::string(),
388 base::Time())); 352 base::Time()));
389 return request.PassAs<Request>(); 353 return request.PassAs<Request>();
390 } 354 }
391 355
392 const CacheEntry* cache_entry = GetCacheEntry(scopes); 356 const CacheEntry* cache_entry = GetCacheEntry(scopes);
393 if (cache_entry && cache_entry->access_token.length()) { 357 if (cache_entry && cache_entry->access_token.length()) {
394 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 358 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
395 &OAuth2TokenService::InformConsumer, 359 &OAuth2TokenService::InformConsumer,
396 request->AsWeakPtr(), 360 request->AsWeakPtr(),
397 GoogleServiceAuthError(GoogleServiceAuthError::NONE), 361 GoogleServiceAuthError(GoogleServiceAuthError::NONE),
398 cache_entry->access_token, 362 cache_entry->access_token,
399 cache_entry->expiration_date)); 363 cache_entry->expiration_date));
400 return request.PassAs<Request>(); 364 return request.PassAs<Request>();
401 } 365 }
402 366
403 std::string refresh_token = token_service->GetOAuth2LoginRefreshToken();
404 if (!refresh_token.length()) {
405 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
406 &OAuth2TokenService::InformConsumer,
407 request->AsWeakPtr(),
408 GoogleServiceAuthError(
409 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS),
410 std::string(),
411 base::Time()));
412 return request.PassAs<Request>();
413 }
414
415 // Makes sure there is a pending fetcher for |scopes| and |refresh_token|. 367 // Makes sure there is a pending fetcher for |scopes| and |refresh_token|.
416 // Adds |request| to the waiting request list of this fetcher so |request| 368 // Adds |request| to the waiting request list of this fetcher so |request|
417 // will be called back when this fetcher finishes fetching. 369 // will be called back when this fetcher finishes fetching.
418 FetchParameters fetch_parameters = std::make_pair(refresh_token, scopes); 370 FetchParameters fetch_parameters = std::make_pair(refresh_token, scopes);
419 std::map<FetchParameters, Fetcher*>::iterator iter = 371 std::map<FetchParameters, Fetcher*>::iterator iter =
420 pending_fetchers_.find(fetch_parameters); 372 pending_fetchers_.find(fetch_parameters);
421 if (iter != pending_fetchers_.end()) { 373 if (iter != pending_fetchers_.end()) {
422 iter->second->AddWaitingRequest(request->AsWeakPtr()); 374 iter->second->AddWaitingRequest(request->AsWeakPtr());
423 return request.PassAs<Request>(); 375 return request.PassAs<Request>();
424 } 376 }
425 pending_fetchers_[fetch_parameters] = Fetcher::CreateAndStart( 377 pending_fetchers_[fetch_parameters] = Fetcher::CreateAndStart(
426 profile_, getter_, refresh_token, scopes, request->AsWeakPtr()); 378 this, request_context_getter_, refresh_token, scopes,
379 request->AsWeakPtr());
427 return request.PassAs<Request>(); 380 return request.PassAs<Request>();
428 } 381 }
429 382
430 void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) { 383 void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) {
431 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 384 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
432 385
433 // Update the auth error state so auth errors are appropriately communicated 386 // Update the auth error state so auth errors are appropriately communicated
434 // to the user. 387 // to the user.
435 UpdateAuthError(fetcher->error()); 388 UpdateAuthError(fetcher->error());
436 389
437 // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh 390 // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh
438 // token and scope set. This is guaranteed as follows; here a Fetcher is said 391 // token and scope set. This is guaranteed as follows; here a Fetcher is said
439 // to be uncompleted if it has not finished calling back 392 // to be uncompleted if it has not finished calling back
440 // OAuth2TokenService::OnFetchComplete(). 393 // OAuth2TokenService::OnFetchComplete().
441 // 394 //
442 // (1) All the live Fetchers are created by this service. 395 // (1) All the live Fetchers are created by this service.
443 // This is because (1) all the live Fetchers are created by a live 396 // This is because (1) all the live Fetchers are created by a live
444 // service, as all the fetchers created by a service are destructed in the 397 // service, as all the fetchers created by a service are destructed in the
445 // service's dtor, and (2) there is at most one live OAuth2TokenSevice for 398 // service's dtor.
446 // a given profile at a time.
447 // 399 //
448 // (2) All the uncompleted Fetchers created by this service are recorded in 400 // (2) All the uncompleted Fetchers created by this service are recorded in
449 // |pending_fetchers_|. 401 // |pending_fetchers_|.
450 // This is because (1) all the created Fetchers are added to 402 // This is because (1) all the created Fetchers are added to
451 // |pending_fetchers_| (in method StartRequest()) and (2) method 403 // |pending_fetchers_| (in method StartRequest()) and (2) method
452 // OnFetchComplete() is the only place where a Fetcher is erased from 404 // OnFetchComplete() is the only place where a Fetcher is erased from
453 // |pending_fetchers_|. Note no Fetcher is erased in method 405 // |pending_fetchers_|. Note no Fetcher is erased in method
454 // StartRequest(). 406 // StartRequest().
455 // 407 //
456 // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its 408 // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its
457 // refresh token and ScopeSet. This is guaranteed by Fetcher creation in 409 // refresh token and ScopeSet. This is guaranteed by Fetcher creation in
458 // method StartReuest(). 410 // method StartRequest().
459 // 411 //
460 // When this method is called, |fetcher| is alive and uncompleted. 412 // When this method is called, |fetcher| is alive and uncompleted.
461 // By (1), |fetcher| is created by this service. 413 // By (1), |fetcher| is created by this service.
462 // Then by (2), |fetcher| is recorded in |pending_fetchers_|. 414 // Then by (2), |fetcher| is recorded in |pending_fetchers_|.
463 // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet. 415 // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet.
464 std::map<FetchParameters, Fetcher*>::iterator iter = 416 std::map<FetchParameters, Fetcher*>::iterator iter =
465 pending_fetchers_.find(std::make_pair( 417 pending_fetchers_.find(std::make_pair(
466 fetcher->GetRefreshToken(), fetcher->GetScopeSet())); 418 fetcher->GetRefreshToken(), fetcher->GetScopeSet()));
467 DCHECK(iter != pending_fetchers_.end()); 419 DCHECK(iter != pending_fetchers_.end());
468 DCHECK_EQ(fetcher, iter->second); 420 DCHECK_EQ(fetcher, iter->second);
(...skipping 13 matching lines...) Expand all
482 return &token_iterator->second; 434 return &token_iterator->second;
483 } 435 }
484 436
485 void OAuth2TokenService::RegisterCacheEntry( 437 void OAuth2TokenService::RegisterCacheEntry(
486 const std::string& refresh_token, 438 const std::string& refresh_token,
487 const OAuth2TokenService::ScopeSet& scopes, 439 const OAuth2TokenService::ScopeSet& scopes,
488 const std::string& access_token, 440 const std::string& access_token,
489 const base::Time& expiration_date) { 441 const base::Time& expiration_date) {
490 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 442 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
491 443
492 // Only register OAuth2 access tokens for the refresh token held by
493 // TokenService.
494 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_);
495 if (!token_service ||
496 !token_service->HasOAuthLoginToken() ||
497 token_service->GetOAuth2LoginRefreshToken().compare(refresh_token) != 0) {
498 DLOG(INFO) <<
499 "Received a token with a refresh token not maintained by TokenService.";
500 return;
501 }
502
503 CacheEntry& token = token_cache_[scopes]; 444 CacheEntry& token = token_cache_[scopes];
504 token.access_token = access_token; 445 token.access_token = access_token;
505 token.expiration_date = expiration_date; 446 token.expiration_date = expiration_date;
506 } 447 }
507 448
508 void OAuth2TokenService::Observe(int type, 449 void OAuth2TokenService::UpdateAuthError(const GoogleServiceAuthError& error) {
509 const content::NotificationSource& source, 450 // Default implementation does nothing.
510 const content::NotificationDetails& details) {
511 DCHECK(type == chrome::NOTIFICATION_TOKENS_CLEARED ||
512 type == chrome::NOTIFICATION_TOKEN_AVAILABLE);
513 if (type == chrome::NOTIFICATION_TOKEN_AVAILABLE) {
514 TokenService::TokenAvailableDetails* tok_details =
515 content::Details<TokenService::TokenAvailableDetails>(details).ptr();
516 if (tok_details->service() != GaiaConstants::kGaiaOAuth2LoginRefreshToken)
517 return;
518 }
519 // The GaiaConstants::kGaiaOAuth2LoginRefreshToken token is used to create
520 // OAuth2 access tokens. If this token either changes or is cleared, any
521 // available tokens must be invalidated.
522 token_cache_.clear();
523 UpdateAuthError(GoogleServiceAuthError::AuthErrorNone());
524 } 451 }
525 452
526 void OAuth2TokenService::UpdateAuthError(const GoogleServiceAuthError& error) { 453 void OAuth2TokenService::ClearCache() {
527 // Do not report connection errors as these are not actually auth errors. 454 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
528 // We also want to avoid masking a "real" auth error just because we 455 token_cache_.clear();
529 // subsequently get a transient network error.
530 if (error.state() == GoogleServiceAuthError::CONNECTION_FAILED)
531 return;
532
533 if (error.state() != last_auth_error_.state()) {
534 last_auth_error_ = error;
535 SigninManagerFactory::GetForProfile(profile_)->signin_global_error()->
536 AuthStatusChanged();
537 }
538 } 456 }
539 457
540 GoogleServiceAuthError OAuth2TokenService::GetAuthStatus() const { 458 int OAuth2TokenService::cache_size_for_testing() const {
541 return last_auth_error_; 459 return token_cache_.size();
542 } 460 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698