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 #include "chrome/browser/net/gaia/gaia_oauth_fetcher.h"
6
7 #include <string>
8 #include <utility>
9 #include <vector>
10
11 #include "base/json/json_reader.h"
12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h"
14 #include "base/values.h"
15 #include "chrome/browser/net/gaia/gaia_oauth_consumer.h"
16 #include "google_apis/gaia/gaia_auth_fetcher.h"
17 #include "google_apis/gaia/gaia_constants.h"
18 #include "google_apis/gaia/gaia_urls.h"
19 #include "google_apis/gaia/oauth_request_signer.h"
20 #include "grit/chromium_strings.h"
21 #include "net/base/load_flags.h"
22 #include "net/cookies/parsed_cookie.h"
23 #include "net/http/http_status_code.h"
24 #include "net/url_request/url_fetcher.h"
25 #include "net/url_request/url_request_context_getter.h"
26 #include "net/url_request/url_request_status.h"
27 #include "ui/base/l10n/l10n_util.h"
28
29 static const char kOAuthTokenCookie[] = "oauth_token";
30
GaiaOAuthFetcher(GaiaOAuthConsumer * consumer,net::URLRequestContextGetter * getter,const std::string & service_scope)31 GaiaOAuthFetcher::GaiaOAuthFetcher(GaiaOAuthConsumer* consumer,
32 net::URLRequestContextGetter* getter,
33 const std::string& service_scope)
34 : consumer_(consumer),
35 getter_(getter),
36 service_scope_(service_scope),
37 fetch_pending_(false),
38 auto_fetch_limit_(USER_INFO) {}
39
~GaiaOAuthFetcher()40 GaiaOAuthFetcher::~GaiaOAuthFetcher() {}
41
HasPendingFetch() const42 bool GaiaOAuthFetcher::HasPendingFetch() const {
43 return fetch_pending_;
44 }
45
CancelRequest()46 void GaiaOAuthFetcher::CancelRequest() {
47 fetcher_.reset();
48 fetch_pending_ = false;
49 }
50
51 // static
CreateGaiaFetcher(net::URLRequestContextGetter * getter,const GURL & gaia_gurl,const std::string & body,const std::string & headers,bool send_cookies,net::URLFetcherDelegate * delegate)52 net::URLFetcher* GaiaOAuthFetcher::CreateGaiaFetcher(
53 net::URLRequestContextGetter* getter,
54 const GURL& gaia_gurl,
55 const std::string& body,
56 const std::string& headers,
57 bool send_cookies,
58 net::URLFetcherDelegate* delegate) {
59 bool empty_body = body.empty();
60 net::URLFetcher* result = net::URLFetcher::Create(
61 0, gaia_gurl,
62 empty_body ? net::URLFetcher::GET : net::URLFetcher::POST,
63 delegate);
64 result->SetRequestContext(getter);
65 // Fetchers are sometimes cancelled because a network change was detected,
66 // especially at startup and after sign-in on ChromeOS. Retrying once should
67 // be enough in those cases; let the fetcher retry up to 3 times just in case.
68 // http://crbug.com/163710
69 result->SetAutomaticallyRetryOnNetworkChanges(3);
70
71 // The Gaia/OAuth token exchange requests do not require any cookie-based
72 // identification as part of requests. We suppress sending any cookies to
73 // maintain a separation between the user's browsing and Chrome's internal
74 // services. Where such mixing is desired (prelogin, autologin
75 // or chromeos login), it will be done explicitly.
76 if (!send_cookies)
77 result->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES);
78
79 if (!empty_body)
80 result->SetUploadData("application/x-www-form-urlencoded", body);
81 if (!headers.empty())
82 result->SetExtraRequestHeaders(headers);
83
84 return result;
85 }
86
87 // static
MakeGetOAuthTokenUrl(const std::string & oauth1_login_scope,const std::string & product_name)88 GURL GaiaOAuthFetcher::MakeGetOAuthTokenUrl(
89 const std::string& oauth1_login_scope,
90 const std::string& product_name) {
91 return GaiaUrls::GetInstance()->get_oauth_token_url().Resolve(
92 "?scope=" + oauth1_login_scope +
93 "&xoauth_display_name=" +
94 OAuthRequestSigner::Encode(product_name));
95 }
96
97 // static
MakeOAuthLoginBody(const char * source,const char * service,const std::string & oauth1_access_token,const std::string & oauth1_access_token_secret)98 std::string GaiaOAuthFetcher::MakeOAuthLoginBody(
99 const char* source,
100 const char* service,
101 const std::string& oauth1_access_token,
102 const std::string& oauth1_access_token_secret) {
103 OAuthRequestSigner::Parameters parameters;
104 parameters["service"] = service;
105 parameters["source"] = source;
106 std::string signed_request;
107 bool is_signed = OAuthRequestSigner::SignURL(
108 GaiaUrls::GetInstance()->oauth1_login_url(),
109 parameters,
110 OAuthRequestSigner::HMAC_SHA1_SIGNATURE,
111 OAuthRequestSigner::POST_METHOD,
112 "anonymous", // oauth_consumer_key
113 "anonymous", // consumer secret
114 oauth1_access_token, // oauth_token
115 oauth1_access_token_secret, // token secret
116 &signed_request);
117 DCHECK(is_signed);
118 return signed_request;
119 }
120
121 // static
MakeOAuthGetAccessTokenBody(const std::string & oauth1_request_token)122 std::string GaiaOAuthFetcher::MakeOAuthGetAccessTokenBody(
123 const std::string& oauth1_request_token) {
124 OAuthRequestSigner::Parameters empty_parameters;
125 std::string signed_request;
126 bool is_signed = OAuthRequestSigner::SignURL(
127 GaiaUrls::GetInstance()->oauth_get_access_token_url(),
128 empty_parameters,
129 OAuthRequestSigner::HMAC_SHA1_SIGNATURE,
130 OAuthRequestSigner::POST_METHOD,
131 "anonymous", // oauth_consumer_key
132 "anonymous", // consumer secret
133 oauth1_request_token, // oauth_token
134 "", // token secret
135 &signed_request);
136 DCHECK(is_signed);
137 return signed_request;
138 }
139
140 // static
MakeOAuthWrapBridgeBody(const std::string & oauth1_access_token,const std::string & oauth1_access_token_secret,const std::string & wrap_token_duration,const std::string & oauth2_scope)141 std::string GaiaOAuthFetcher::MakeOAuthWrapBridgeBody(
142 const std::string& oauth1_access_token,
143 const std::string& oauth1_access_token_secret,
144 const std::string& wrap_token_duration,
145 const std::string& oauth2_scope) {
146 OAuthRequestSigner::Parameters parameters;
147 parameters["wrap_token_duration"] = wrap_token_duration;
148 parameters["wrap_scope"] = oauth2_scope;
149 std::string signed_request;
150 bool is_signed = OAuthRequestSigner::SignURL(
151 GaiaUrls::GetInstance()->oauth_wrap_bridge_url(),
152 parameters,
153 OAuthRequestSigner::HMAC_SHA1_SIGNATURE,
154 OAuthRequestSigner::POST_METHOD,
155 "anonymous", // oauth_consumer_key
156 "anonymous", // consumer secret
157 oauth1_access_token, // oauth_token
158 oauth1_access_token_secret, // token secret
159 &signed_request);
160 DCHECK(is_signed);
161 return signed_request;
162 }
163
164 // Helper method that extracts tokens from a successful reply.
165 // static
ParseOAuthLoginResponse(const std::string & data,std::string * sid,std::string * lsid,std::string * auth)166 void GaiaOAuthFetcher::ParseOAuthLoginResponse(
167 const std::string& data,
168 std::string* sid,
169 std::string* lsid,
170 std::string* auth) {
171 using std::vector;
172 using std::pair;
173 using std::string;
174 vector<pair<string, string> > tokens;
175 base::SplitStringIntoKeyValuePairs(data, '=', '\n', &tokens);
176 for (vector<pair<string, string> >::iterator i = tokens.begin();
177 i != tokens.end(); ++i) {
178 if (i->first == "SID") {
179 *sid = i->second;
180 } else if (i->first == "LSID") {
181 *lsid = i->second;
182 } else if (i->first == "Auth") {
183 *auth = i->second;
184 }
185 }
186 }
187
188 // Helper method that extracts tokens from a successful reply.
189 // static
ParseOAuthGetAccessTokenResponse(const std::string & data,std::string * token,std::string * secret)190 void GaiaOAuthFetcher::ParseOAuthGetAccessTokenResponse(
191 const std::string& data,
192 std::string* token,
193 std::string* secret) {
194 using std::vector;
195 using std::pair;
196 using std::string;
197
198 vector<pair<string, string> > tokens;
199 base::SplitStringIntoKeyValuePairs(data, '=', '&', &tokens);
200 for (vector<pair<string, string> >::iterator i = tokens.begin();
201 i != tokens.end(); ++i) {
202 if (i->first == "oauth_token") {
203 std::string decoded;
204 if (OAuthRequestSigner::Decode(i->second, &decoded))
205 token->assign(decoded);
206 } else if (i->first == "oauth_token_secret") {
207 std::string decoded;
208 if (OAuthRequestSigner::Decode(i->second, &decoded))
209 secret->assign(decoded);
210 }
211 }
212 }
213
214 // Helper method that extracts tokens from a successful reply.
215 // static
ParseOAuthWrapBridgeResponse(const std::string & data,std::string * token,std::string * expires_in)216 void GaiaOAuthFetcher::ParseOAuthWrapBridgeResponse(const std::string& data,
217 std::string* token,
218 std::string* expires_in) {
219 using std::vector;
220 using std::pair;
221 using std::string;
222
223 vector<pair<string, string> > tokens;
224 base::SplitStringIntoKeyValuePairs(data, '=', '&', &tokens);
225 for (vector<pair<string, string> >::iterator i = tokens.begin();
226 i != tokens.end(); ++i) {
227 if (i->first == "wrap_access_token") {
228 std::string decoded;
229 if (OAuthRequestSigner::Decode(i->second, &decoded))
230 token->assign(decoded);
231 } else if (i->first == "wrap_access_token_expires_in") {
232 std::string decoded;
233 if (OAuthRequestSigner::Decode(i->second, &decoded))
234 expires_in->assign(decoded);
235 }
236 }
237 }
238
239 // Helper method that extracts tokens from a successful reply.
240 // static
ParseUserInfoResponse(const std::string & data,std::string * email_result)241 void GaiaOAuthFetcher::ParseUserInfoResponse(const std::string& data,
242 std::string* email_result) {
243 scoped_ptr<base::Value> value(base::JSONReader::Read(data));
244 if (value->GetType() == base::Value::TYPE_DICTIONARY) {
245 Value* email_value;
246 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
247 if (dict->Get("email", &email_value)) {
248 if (email_value->GetType() == base::Value::TYPE_STRING) {
249 email_value->GetAsString(email_result);
250 }
251 }
252 }
253 }
254
StartOAuthLogin(const char * source,const char * service,const std::string & oauth1_access_token,const std::string & oauth1_access_token_secret)255 void GaiaOAuthFetcher::StartOAuthLogin(
256 const char* source,
257 const char* service,
258 const std::string& oauth1_access_token,
259 const std::string& oauth1_access_token_secret) {
260 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
261
262 request_type_ = OAUTH1_LOGIN;
263 // Must outlive fetcher_.
264 request_body_ = MakeOAuthLoginBody(source, service, oauth1_access_token,
265 oauth1_access_token_secret);
266 request_headers_ = "";
267 GURL url(GaiaUrls::GetInstance()->oauth1_login_url());
268 fetcher_.reset(CreateGaiaFetcher(getter_, url, request_body_,
269 request_headers_, false, this));
270 fetch_pending_ = true;
271 fetcher_->Start();
272 }
273
StartGetOAuthTokenRequest()274 void GaiaOAuthFetcher::StartGetOAuthTokenRequest() {
275 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
276
277 request_type_ = OAUTH1_REQUEST_TOKEN;
278 // Must outlive fetcher_.
279 request_body_ = "";
280 request_headers_ = "";
281 fetcher_.reset(CreateGaiaFetcher(getter_,
282 MakeGetOAuthTokenUrl(GaiaUrls::GetInstance()->oauth1_login_scope(),
283 l10n_util::GetStringUTF8(IDS_PRODUCT_NAME)),
284 std::string(),
285 std::string(),
286 true, // send_cookies
287 this));
288 fetch_pending_ = true;
289 fetcher_->Start();
290 }
291
StartOAuthGetAccessToken(const std::string & oauth1_request_token)292 void GaiaOAuthFetcher::StartOAuthGetAccessToken(
293 const std::string& oauth1_request_token) {
294 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
295
296 request_type_ = OAUTH1_ALL_ACCESS_TOKEN;
297 // Must outlive fetcher_.
298 request_body_ = MakeOAuthGetAccessTokenBody(oauth1_request_token);
299 request_headers_ = "";
300 GURL url(GaiaUrls::GetInstance()->oauth_get_access_token_url());
301 fetcher_.reset(CreateGaiaFetcher(getter_, url, request_body_,
302 request_headers_, false, this));
303 fetch_pending_ = true;
304 fetcher_->Start();
305 }
306
StartOAuthWrapBridge(const std::string & oauth1_access_token,const std::string & oauth1_access_token_secret,const std::string & wrap_token_duration,const std::string & service_scope)307 void GaiaOAuthFetcher::StartOAuthWrapBridge(
308 const std::string& oauth1_access_token,
309 const std::string& oauth1_access_token_secret,
310 const std::string& wrap_token_duration,
311 const std::string& service_scope) {
312 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
313
314 request_type_ = OAUTH2_SERVICE_ACCESS_TOKEN;
315 VLOG(1) << "Starting OAuthWrapBridge for: " << service_scope;
316 std::string combined_scope = service_scope + " " +
317 GaiaUrls::GetInstance()->oauth_wrap_bridge_user_info_scope();
318 service_scope_ = service_scope;
319
320 // Must outlive fetcher_.
321 request_body_ = MakeOAuthWrapBridgeBody(
322 oauth1_access_token,
323 oauth1_access_token_secret,
324 wrap_token_duration,
325 combined_scope);
326
327 request_headers_ = "";
328 GURL url(GaiaUrls::GetInstance()->oauth_wrap_bridge_url());
329 fetcher_.reset(CreateGaiaFetcher(getter_, url, request_body_,
330 request_headers_, false, this));
331 fetch_pending_ = true;
332 fetcher_->Start();
333 }
334
StartUserInfo(const std::string & oauth2_access_token)335 void GaiaOAuthFetcher::StartUserInfo(const std::string& oauth2_access_token) {
336 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
337
338 request_type_ = USER_INFO;
339 // Must outlive fetcher_.
340 request_body_ = "";
341 request_headers_ = "Authorization: OAuth " + oauth2_access_token;
342 GURL url(GaiaUrls::GetInstance()->oauth_user_info_url());
343 fetcher_.reset(CreateGaiaFetcher(getter_, url, request_body_,
344 request_headers_, false, this));
345 fetch_pending_ = true;
346 fetcher_->Start();
347 }
348
StartOAuthRevokeAccessToken(const std::string & token,const std::string & secret)349 void GaiaOAuthFetcher::StartOAuthRevokeAccessToken(const std::string& token,
350 const std::string& secret) {
351 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
352
353 request_type_ = OAUTH2_REVOKE_TOKEN;
354 // Must outlive fetcher_.
355 request_body_ = "";
356
357 OAuthRequestSigner::Parameters empty_parameters;
358 std::string auth_header;
359 bool is_signed = OAuthRequestSigner::SignAuthHeader(
360 GaiaUrls::GetInstance()->oauth_revoke_token_url(),
361 empty_parameters,
362 OAuthRequestSigner::HMAC_SHA1_SIGNATURE,
363 OAuthRequestSigner::GET_METHOD,
364 "anonymous",
365 "anonymous",
366 token,
367 secret,
368 &auth_header);
369 DCHECK(is_signed);
370 request_headers_ = "Authorization: " + auth_header;
371 GURL url(GaiaUrls::GetInstance()->oauth_revoke_token_url());
372 fetcher_.reset(CreateGaiaFetcher(getter_, url, request_body_,
373 request_headers_, false, this));
374 fetch_pending_ = true;
375 fetcher_->Start();
376 }
377
StartOAuthRevokeWrapToken(const std::string & token)378 void GaiaOAuthFetcher::StartOAuthRevokeWrapToken(const std::string& token) {
379 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
380
381 request_type_ = OAUTH2_REVOKE_TOKEN;
382 // Must outlive fetcher_.
383 request_body_ = "";
384
385 request_headers_ = "Authorization: Bearer " + token;
386 GURL url(GaiaUrls::GetInstance()->oauth_revoke_token_url());
387 fetcher_.reset(CreateGaiaFetcher(getter_, url, request_body_,
388 request_headers_, false, this));
389 fetch_pending_ = true;
390 fetcher_->Start();
391 }
392
393 // static
GenerateAuthError(const std::string & data,const net::URLRequestStatus & status,int response_code)394 GoogleServiceAuthError GaiaOAuthFetcher::GenerateAuthError(
395 const std::string& data,
396 const net::URLRequestStatus& status,
397 int response_code) {
398 if (!status.is_success()) {
399 if (status.status() == net::URLRequestStatus::CANCELED) {
400 return GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
401 } else {
402 LOG(WARNING) << "Could not reach Google Accounts servers: errno "
403 << status.error();
404 return GoogleServiceAuthError::FromConnectionError(status.error());
405 }
406 } else {
407 LOG(WARNING) << "Unrecognized response from Google Accounts servers "
408 << "code " << response_code << " data " << data;
409 return GoogleServiceAuthError(
410 GoogleServiceAuthError::SERVICE_UNAVAILABLE);
411 }
412
413 NOTREACHED();
414 return GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE);
415 }
416
OnGetOAuthTokenUrlFetched(const net::ResponseCookies & cookies,const net::URLRequestStatus & status,int response_code)417 void GaiaOAuthFetcher::OnGetOAuthTokenUrlFetched(
418 const net::ResponseCookies& cookies,
419 const net::URLRequestStatus& status,
420 int response_code) {
421 if (status.is_success() && response_code == net::HTTP_OK) {
422 for (net::ResponseCookies::const_iterator iter = cookies.begin();
423 iter != cookies.end(); ++iter) {
424 net::ParsedCookie cookie(*iter);
425 if (cookie.Name() == kOAuthTokenCookie) {
426 std::string token = cookie.Value();
427 consumer_->OnGetOAuthTokenSuccess(token);
428 if (ShouldAutoFetch(OAUTH1_ALL_ACCESS_TOKEN))
429 StartOAuthGetAccessToken(token);
430 return;
431 }
432 }
433 }
434 consumer_->OnGetOAuthTokenFailure(
435 GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE));
436 }
437
OnOAuthLoginFetched(const std::string & data,const net::URLRequestStatus & status,int response_code)438 void GaiaOAuthFetcher::OnOAuthLoginFetched(
439 const std::string& data,
440 const net::URLRequestStatus& status,
441 int response_code) {
442 if (status.is_success() && response_code == net::HTTP_OK) {
443 std::string sid;
444 std::string lsid;
445 std::string auth;
446 ParseOAuthLoginResponse(data, &sid, &lsid, &auth);
447 if (!sid.empty() && !lsid.empty() && !auth.empty()) {
448 consumer_->OnOAuthLoginSuccess(sid, lsid, auth);
449 return;
450 }
451 }
452 // OAuthLogin returns error messages that are identical to ClientLogin,
453 // so we use GaiaAuthFetcher::GenerateAuthError to parse the response
454 // instead.
455 consumer_->OnOAuthLoginFailure(
456 GaiaAuthFetcher::GenerateOAuthLoginError(data, status));
457 }
458
OnOAuthGetAccessTokenFetched(const std::string & data,const net::URLRequestStatus & status,int response_code)459 void GaiaOAuthFetcher::OnOAuthGetAccessTokenFetched(
460 const std::string& data,
461 const net::URLRequestStatus& status,
462 int response_code) {
463 if (status.is_success() && response_code == net::HTTP_OK) {
464 VLOG(1) << "OAuth1 access token fetched.";
465 std::string secret;
466 std::string token;
467 ParseOAuthGetAccessTokenResponse(data, &token, &secret);
468 if (!token.empty() && !secret.empty()) {
469 consumer_->OnOAuthGetAccessTokenSuccess(token, secret);
470 if (ShouldAutoFetch(OAUTH2_SERVICE_ACCESS_TOKEN))
471 StartOAuthWrapBridge(
472 token, secret, GaiaConstants::kGaiaOAuthDuration, service_scope_);
473 return;
474 }
475 }
476 consumer_->OnOAuthGetAccessTokenFailure(GenerateAuthError(data, status,
477 response_code));
478 }
479
OnOAuthWrapBridgeFetched(const std::string & data,const net::URLRequestStatus & status,int response_code)480 void GaiaOAuthFetcher::OnOAuthWrapBridgeFetched(
481 const std::string& data,
482 const net::URLRequestStatus& status,
483 int response_code) {
484 if (status.is_success() && response_code == net::HTTP_OK) {
485 VLOG(1) << "OAuth2 access token fetched.";
486 std::string token;
487 std::string expires_in;
488 ParseOAuthWrapBridgeResponse(data, &token, &expires_in);
489 if (!token.empty() && !expires_in.empty()) {
490 consumer_->OnOAuthWrapBridgeSuccess(service_scope_, token, expires_in);
491 if (ShouldAutoFetch(USER_INFO))
492 StartUserInfo(token);
493 return;
494 }
495 }
496 consumer_->OnOAuthWrapBridgeFailure(service_scope_,
497 GenerateAuthError(data, status,
498 response_code));
499 }
500
OnOAuthRevokeTokenFetched(const std::string & data,const net::URLRequestStatus & status,int response_code)501 void GaiaOAuthFetcher::OnOAuthRevokeTokenFetched(
502 const std::string& data,
503 const net::URLRequestStatus& status,
504 int response_code) {
505 if (status.is_success() && response_code == net::HTTP_OK) {
506 consumer_->OnOAuthRevokeTokenSuccess();
507 } else {
508 LOG(ERROR) << "Token revocation failure " << response_code << ": " << data;
509 consumer_->OnOAuthRevokeTokenFailure(GenerateAuthError(data, status,
510 response_code));
511 }
512 }
513
OnUserInfoFetched(const std::string & data,const net::URLRequestStatus & status,int response_code)514 void GaiaOAuthFetcher::OnUserInfoFetched(
515 const std::string& data,
516 const net::URLRequestStatus& status,
517 int response_code) {
518 if (status.is_success() && response_code == net::HTTP_OK) {
519 std::string email;
520 ParseUserInfoResponse(data, &email);
521 if (!email.empty()) {
522 VLOG(1) << "GAIA user info fetched for " << email << ".";
523 consumer_->OnUserInfoSuccess(email);
524 return;
525 }
526 }
527 consumer_->OnUserInfoFailure(GenerateAuthError(data, status,
528 response_code));
529 }
530
OnURLFetchComplete(const net::URLFetcher * source)531 void GaiaOAuthFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
532 // Keep |fetcher_| around to avoid invalidating its |status| (accessed below).
533 scoped_ptr<net::URLFetcher> current_fetcher(fetcher_.release());
534 fetch_pending_ = false;
535 std::string data;
536 source->GetResponseAsString(&data);
537 net::URLRequestStatus status = source->GetStatus();
538 int response_code = source->GetResponseCode();
539
540 switch (request_type_) {
541 case OAUTH1_LOGIN:
542 OnOAuthLoginFetched(data, status, response_code);
543 break;
544 case OAUTH1_REQUEST_TOKEN:
545 OnGetOAuthTokenUrlFetched(source->GetCookies(), status, response_code);
546 break;
547 case OAUTH1_ALL_ACCESS_TOKEN:
548 OnOAuthGetAccessTokenFetched(data, status, response_code);
549 break;
550 case OAUTH2_SERVICE_ACCESS_TOKEN:
551 OnOAuthWrapBridgeFetched(data, status, response_code);
552 break;
553 case USER_INFO:
554 OnUserInfoFetched(data, status, response_code);
555 break;
556 case OAUTH2_REVOKE_TOKEN:
557 OnOAuthRevokeTokenFetched(data, status, response_code);
558 break;
559 }
560 }
561
ShouldAutoFetch(RequestType fetch_step)562 bool GaiaOAuthFetcher::ShouldAutoFetch(RequestType fetch_step) {
563 return fetch_step <= auto_fetch_limit_;
564 }
565