OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/common/net/gaia/gaia_auth_fetcher.h" | 5 #include "chrome/common/net/gaia/gaia_auth_fetcher.h" |
6 | 6 |
7 #include <algorithm> | |
8 #include <string> | 7 #include <string> |
9 #include <utility> | 8 #include <utility> |
10 #include <vector> | 9 #include <vector> |
11 | 10 |
12 #include "base/json/json_reader.h" | |
13 #include "base/string_split.h" | 11 #include "base/string_split.h" |
14 #include "base/string_util.h" | 12 #include "base/string_util.h" |
15 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
16 #include "base/values.h" | |
17 #include "chrome/common/net/gaia/gaia_auth_consumer.h" | 14 #include "chrome/common/net/gaia/gaia_auth_consumer.h" |
18 #include "chrome/common/net/gaia/gaia_constants.h" | 15 #include "chrome/common/net/gaia/gaia_constants.h" |
19 #include "chrome/common/net/gaia/gaia_urls.h" | 16 #include "chrome/common/net/gaia/gaia_urls.h" |
20 #include "chrome/common/net/gaia/google_service_auth_error.h" | 17 #include "chrome/common/net/gaia/google_service_auth_error.h" |
21 #include "chrome/common/net/http_return.h" | 18 #include "chrome/common/net/http_return.h" |
22 #include "content/public/common/url_fetcher.h" | 19 #include "content/public/common/url_fetcher.h" |
23 #include "net/base/escape.h" | 20 #include "net/base/escape.h" |
24 #include "net/base/load_flags.h" | 21 #include "net/base/load_flags.h" |
25 #include "net/url_request/url_request_context_getter.h" | 22 #include "net/url_request/url_request_context_getter.h" |
26 #include "net/url_request/url_request_status.h" | 23 #include "net/url_request/url_request_status.h" |
27 | 24 |
28 namespace { | |
29 static bool CookiePartsContains(const std::vector<std::string>& parts, | |
30 const char* part) { | |
31 return std::find(parts.begin(), parts.end(), part) != parts.end(); | |
32 } | |
33 } // namespace | |
34 | |
35 // TODO(chron): Add sourceless version of this formatter. | 25 // TODO(chron): Add sourceless version of this formatter. |
36 // static | 26 // static |
37 const char GaiaAuthFetcher::kClientLoginFormat[] = | 27 const char GaiaAuthFetcher::kClientLoginFormat[] = |
38 "Email=%s&" | 28 "Email=%s&" |
39 "Passwd=%s&" | 29 "Passwd=%s&" |
40 "PersistentCookie=%s&" | 30 "PersistentCookie=%s&" |
41 "accountType=%s&" | 31 "accountType=%s&" |
42 "source=%s&" | 32 "source=%s&" |
43 "service=%s"; | 33 "service=%s"; |
44 // static | 34 // static |
45 const char GaiaAuthFetcher::kClientLoginCaptchaFormat[] = | 35 const char GaiaAuthFetcher::kClientLoginCaptchaFormat[] = |
46 "Email=%s&" | 36 "Email=%s&" |
47 "Passwd=%s&" | 37 "Passwd=%s&" |
48 "PersistentCookie=%s&" | 38 "PersistentCookie=%s&" |
49 "accountType=%s&" | 39 "accountType=%s&" |
50 "source=%s&" | 40 "source=%s&" |
51 "service=%s&" | 41 "service=%s&" |
52 "logintoken=%s&" | 42 "logintoken=%s&" |
53 "logincaptcha=%s"; | 43 "logincaptcha=%s"; |
54 // static | 44 // static |
55 const char GaiaAuthFetcher::kIssueAuthTokenFormat[] = | 45 const char GaiaAuthFetcher::kIssueAuthTokenFormat[] = |
56 "SID=%s&" | 46 "SID=%s&" |
57 "LSID=%s&" | 47 "LSID=%s&" |
58 "service=%s&" | 48 "service=%s&" |
59 "Session=%s"; | 49 "Session=%s"; |
60 // static | 50 // static |
61 const char GaiaAuthFetcher::kClientLoginToOAuth2BodyFormat[] = | |
62 "scope=%s&client_id=%s"; | |
63 // static | |
64 const char GaiaAuthFetcher::kOAuth2CodeToTokenPairBodyFormat[] = | |
65 "scope=%s&" | |
66 "grant_type=authorization_code&" | |
67 "client_id=%s&" | |
68 "client_secret=%s&" | |
69 "code=%s"; | |
70 // static | |
71 const char GaiaAuthFetcher::kGetUserInfoFormat[] = | 51 const char GaiaAuthFetcher::kGetUserInfoFormat[] = |
72 "LSID=%s"; | 52 "LSID=%s"; |
73 // static | 53 // static |
74 const char GaiaAuthFetcher::kTokenAuthFormat[] = | 54 const char GaiaAuthFetcher::kTokenAuthFormat[] = |
75 "auth=%s&" | 55 "auth=%s&" |
76 "continue=%s&" | 56 "continue=%s&" |
77 "source=%s"; | 57 "source=%s"; |
78 // static | 58 // static |
79 const char GaiaAuthFetcher::kMergeSessionFormat[] = | 59 const char GaiaAuthFetcher::kMergeSessionFormat[] = |
80 "uberauth=%s&" | 60 "uberauth=%s&" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 // TODO(johnnyg): When hosted accounts are supported by sync, | 93 // TODO(johnnyg): When hosted accounts are supported by sync, |
114 // we can always use "HOSTED_OR_GOOGLE" | 94 // we can always use "HOSTED_OR_GOOGLE" |
115 const char GaiaAuthFetcher::kAccountTypeHostedOrGoogle[] = | 95 const char GaiaAuthFetcher::kAccountTypeHostedOrGoogle[] = |
116 "HOSTED_OR_GOOGLE"; | 96 "HOSTED_OR_GOOGLE"; |
117 const char GaiaAuthFetcher::kAccountTypeGoogle[] = | 97 const char GaiaAuthFetcher::kAccountTypeGoogle[] = |
118 "GOOGLE"; | 98 "GOOGLE"; |
119 | 99 |
120 // static | 100 // static |
121 const char GaiaAuthFetcher::kSecondFactor[] = "Info=InvalidSecondFactor"; | 101 const char GaiaAuthFetcher::kSecondFactor[] = "Info=InvalidSecondFactor"; |
122 | 102 |
123 // static | |
124 const char GaiaAuthFetcher::kAuthHeaderFormat[] = | |
125 "Authorization: GoogleLogin auth=%s"; | |
126 // static | |
127 const char GaiaAuthFetcher::kClientLoginToOAuth2CookiePartSecure[] = "Secure"; | |
128 // static | |
129 const char GaiaAuthFetcher::kClientLoginToOAuth2CookiePartHttpOnly[] = | |
130 "HttpOnly"; | |
131 // static | |
132 const char GaiaAuthFetcher::kClientLoginToOAuth2CookiePartCodePrefix[] = | |
133 "oauth_code="; | |
134 // static | |
135 const int GaiaAuthFetcher::kClientLoginToOAuth2CookiePartCodePrefixLength = | |
136 arraysize(GaiaAuthFetcher::kClientLoginToOAuth2CookiePartCodePrefix) - 1; | |
137 // static | |
138 const char GaiaAuthFetcher::kOAuth2RefreshTokenKey[] = "refresh_token"; | |
139 // static | |
140 const char GaiaAuthFetcher::kOAuth2AccessTokenKey[] = "access_token"; | |
141 // static | |
142 const char GaiaAuthFetcher::kOAuth2ExpiresInKey[] = "expires_in"; | |
143 | |
144 GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer, | 103 GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer, |
145 const std::string& source, | 104 const std::string& source, |
146 net::URLRequestContextGetter* getter) | 105 net::URLRequestContextGetter* getter) |
147 : consumer_(consumer), | 106 : consumer_(consumer), |
148 getter_(getter), | 107 getter_(getter), |
149 source_(source), | 108 source_(source), |
150 client_login_gurl_(GaiaUrls::GetInstance()->client_login_url()), | 109 client_login_gurl_(GaiaUrls::GetInstance()->client_login_url()), |
151 issue_auth_token_gurl_(GaiaUrls::GetInstance()->issue_auth_token_url()), | 110 issue_auth_token_gurl_(GaiaUrls::GetInstance()->issue_auth_token_url()), |
152 client_login_to_oauth2_gurl_( | |
153 GaiaUrls::GetInstance()->client_login_to_oauth2_url()), | |
154 oauth2_token_gurl_(GaiaUrls::GetInstance()->oauth2_token_url()), | |
155 get_user_info_gurl_(GaiaUrls::GetInstance()->get_user_info_url()), | 111 get_user_info_gurl_(GaiaUrls::GetInstance()->get_user_info_url()), |
156 token_auth_gurl_(GaiaUrls::GetInstance()->token_auth_url()), | 112 token_auth_gurl_(GaiaUrls::GetInstance()->token_auth_url()), |
157 merge_session_gurl_(GaiaUrls::GetInstance()->merge_session_url()), | 113 merge_session_gurl_(GaiaUrls::GetInstance()->merge_session_url()), |
158 fetch_pending_(false) {} | 114 fetch_pending_(false) {} |
159 | 115 |
160 GaiaAuthFetcher::~GaiaAuthFetcher() {} | 116 GaiaAuthFetcher::~GaiaAuthFetcher() {} |
161 | 117 |
162 bool GaiaAuthFetcher::HasPendingFetch() { | 118 bool GaiaAuthFetcher::HasPendingFetch() { |
163 return fetch_pending_; | 119 return fetch_pending_; |
164 } | 120 } |
165 | 121 |
166 void GaiaAuthFetcher::CancelRequest() { | 122 void GaiaAuthFetcher::CancelRequest() { |
167 fetcher_.reset(); | 123 fetcher_.reset(); |
168 fetch_pending_ = false; | 124 fetch_pending_ = false; |
169 } | 125 } |
170 | 126 |
171 // static | 127 // static |
172 content::URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( | 128 content::URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( |
173 net::URLRequestContextGetter* getter, | 129 net::URLRequestContextGetter* getter, |
174 const std::string& body, | 130 const std::string& body, |
175 const std::string& headers, | |
176 const GURL& gaia_gurl, | 131 const GURL& gaia_gurl, |
177 bool use_cookies, | 132 bool send_cookies, |
178 content::URLFetcherDelegate* delegate) { | 133 content::URLFetcherDelegate* delegate) { |
179 content::URLFetcher* to_return = content::URLFetcher::Create( | 134 content::URLFetcher* to_return = content::URLFetcher::Create( |
180 0, gaia_gurl, content::URLFetcher::POST, delegate); | 135 0, gaia_gurl, content::URLFetcher::POST, delegate); |
181 to_return->SetRequestContext(getter); | 136 to_return->SetRequestContext(getter); |
182 to_return->SetUploadData("application/x-www-form-urlencoded", body); | 137 to_return->SetUploadData("application/x-www-form-urlencoded", body); |
183 | 138 |
184 // The Gaia token exchange requests do not require any cookie-based | 139 // The Gaia token exchange requests do not require any cookie-based |
185 // identification as part of requests. We suppress sending any cookies to | 140 // identification as part of requests. We suppress sending any cookies to |
186 // maintain a separation between the user's browsing and Chrome's internal | 141 // maintain a separation between the user's browsing and Chrome's internal |
187 // services. Where such mixing is desired (MergeSession), it will be done | 142 // services. Where such mixing is desired (MergeSession), it will be done |
188 // explicitly. | 143 // explicitly. |
189 if (!use_cookies) { | 144 if (!send_cookies) |
190 to_return->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | 145 to_return->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES); |
191 net::LOAD_DO_NOT_SAVE_COOKIES); | |
192 } | |
193 if (!headers.empty()) | |
194 to_return->SetExtraRequestHeaders(headers); | |
195 | 146 |
196 return to_return; | 147 return to_return; |
197 } | 148 } |
198 | 149 |
199 // static | 150 // static |
200 std::string GaiaAuthFetcher::MakeClientLoginBody( | 151 std::string GaiaAuthFetcher::MakeClientLoginBody( |
201 const std::string& username, | 152 const std::string& username, |
202 const std::string& password, | 153 const std::string& password, |
203 const std::string& source, | 154 const std::string& source, |
204 const char* service, | 155 const char* service, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 session = false; | 202 session = false; |
252 | 203 |
253 return base::StringPrintf(kIssueAuthTokenFormat, | 204 return base::StringPrintf(kIssueAuthTokenFormat, |
254 encoded_sid.c_str(), | 205 encoded_sid.c_str(), |
255 encoded_lsid.c_str(), | 206 encoded_lsid.c_str(), |
256 service, | 207 service, |
257 session ? "true" : "false"); | 208 session ? "true" : "false"); |
258 } | 209 } |
259 | 210 |
260 // static | 211 // static |
261 std::string GaiaAuthFetcher::MakeGetAuthCodeBody() { | |
262 std::string encoded_scope = net::EscapeUrlEncodedData( | |
263 GaiaUrls::GetInstance()->oauth1_login_scope(), true); | |
264 std::string encoded_client_id = net::EscapeUrlEncodedData( | |
265 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), true); | |
266 return StringPrintf(kClientLoginToOAuth2BodyFormat, | |
267 encoded_scope.c_str(), | |
268 encoded_client_id.c_str()); | |
269 } | |
270 | |
271 // static | |
272 std::string GaiaAuthFetcher::MakeGetTokenPairBody( | |
273 const std::string& auth_code) { | |
274 std::string encoded_scope = net::EscapeUrlEncodedData( | |
275 GaiaUrls::GetInstance()->oauth1_login_scope(), true); | |
276 std::string encoded_client_id = net::EscapeUrlEncodedData( | |
277 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), true); | |
278 std::string encoded_client_secret = net::EscapeUrlEncodedData( | |
279 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), true); | |
280 std::string encoded_auth_code = net::EscapeUrlEncodedData(auth_code, true); | |
281 return StringPrintf(kOAuth2CodeToTokenPairBodyFormat, | |
282 encoded_scope.c_str(), | |
283 encoded_client_id.c_str(), | |
284 encoded_client_secret.c_str(), | |
285 encoded_auth_code.c_str()); | |
286 } | |
287 | |
288 // static | |
289 std::string GaiaAuthFetcher::MakeGetUserInfoBody(const std::string& lsid) { | 212 std::string GaiaAuthFetcher::MakeGetUserInfoBody(const std::string& lsid) { |
290 std::string encoded_lsid = net::EscapeUrlEncodedData(lsid, true); | 213 std::string encoded_lsid = net::EscapeUrlEncodedData(lsid, true); |
291 return base::StringPrintf(kGetUserInfoFormat, encoded_lsid.c_str()); | 214 return base::StringPrintf(kGetUserInfoFormat, encoded_lsid.c_str()); |
292 } | 215 } |
293 | 216 |
294 // static | 217 // static |
295 std::string GaiaAuthFetcher::MakeTokenAuthBody(const std::string& auth_token, | 218 std::string GaiaAuthFetcher::MakeTokenAuthBody(const std::string& auth_token, |
296 const std::string& continue_url, | 219 const std::string& continue_url, |
297 const std::string& source) { | 220 const std::string& source) { |
298 std::string encoded_auth_token = net::EscapeUrlEncodedData(auth_token, true); | 221 std::string encoded_auth_token = net::EscapeUrlEncodedData(auth_token, true); |
(...skipping 14 matching lines...) Expand all Loading... |
313 std::string encoded_auth_token = net::EscapeUrlEncodedData(auth_token, true); | 236 std::string encoded_auth_token = net::EscapeUrlEncodedData(auth_token, true); |
314 std::string encoded_continue_url = net::EscapeUrlEncodedData(continue_url, | 237 std::string encoded_continue_url = net::EscapeUrlEncodedData(continue_url, |
315 true); | 238 true); |
316 std::string encoded_source = net::EscapeUrlEncodedData(source, true); | 239 std::string encoded_source = net::EscapeUrlEncodedData(source, true); |
317 return base::StringPrintf(kMergeSessionFormat, | 240 return base::StringPrintf(kMergeSessionFormat, |
318 encoded_auth_token.c_str(), | 241 encoded_auth_token.c_str(), |
319 encoded_continue_url.c_str(), | 242 encoded_continue_url.c_str(), |
320 encoded_source.c_str()); | 243 encoded_source.c_str()); |
321 } | 244 } |
322 | 245 |
323 // static | |
324 std::string GaiaAuthFetcher::MakeGetAuthCodeHeader( | |
325 const std::string& auth_token) { | |
326 return StringPrintf(kAuthHeaderFormat, auth_token.c_str()); | |
327 } | |
328 | |
329 // Helper method that extracts tokens from a successful reply. | 246 // Helper method that extracts tokens from a successful reply. |
330 // static | 247 // static |
331 void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data, | 248 void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data, |
332 std::string* sid, | 249 std::string* sid, |
333 std::string* lsid, | 250 std::string* lsid, |
334 std::string* token) { | 251 std::string* token) { |
335 using std::vector; | 252 using std::vector; |
336 using std::pair; | 253 using std::pair; |
337 using std::string; | 254 using std::string; |
338 | 255 |
(...skipping 30 matching lines...) Expand all Loading... |
369 } else if (i->first == kErrorUrlParam) { | 286 } else if (i->first == kErrorUrlParam) { |
370 error_url->assign(i->second); | 287 error_url->assign(i->second); |
371 } else if (i->first == kCaptchaUrlParam) { | 288 } else if (i->first == kCaptchaUrlParam) { |
372 captcha_url->assign(i->second); | 289 captcha_url->assign(i->second); |
373 } else if (i->first == kCaptchaTokenParam) { | 290 } else if (i->first == kCaptchaTokenParam) { |
374 captcha_token->assign(i->second); | 291 captcha_token->assign(i->second); |
375 } | 292 } |
376 } | 293 } |
377 } | 294 } |
378 | 295 |
379 // static | |
380 bool GaiaAuthFetcher::ParseClientLoginToOAuth2Response( | |
381 const net::ResponseCookies& cookies, | |
382 std::string* auth_code) { | |
383 DCHECK(auth_code); | |
384 net::ResponseCookies::const_iterator iter; | |
385 for (iter = cookies.begin(); iter != cookies.end(); ++iter) { | |
386 if (ParseClientLoginToOAuth2Cookie(*iter, auth_code)) | |
387 return true; | |
388 } | |
389 return false; | |
390 } | |
391 | |
392 // static | |
393 bool GaiaAuthFetcher::ParseOAuth2TokenPairResponse(const std::string& data, | |
394 std::string* refresh_token, | |
395 std::string* access_token, | |
396 int* expires_in_secs) { | |
397 DCHECK(refresh_token); | |
398 DCHECK(access_token); | |
399 base::JSONReader reader; | |
400 scoped_ptr<base::Value> value(reader.Read(data, false)); | |
401 if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY) | |
402 return false; | |
403 | |
404 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); | |
405 std::string rt; | |
406 std::string at; | |
407 int exp; | |
408 | |
409 if (!dict->GetStringWithoutPathExpansion(kOAuth2RefreshTokenKey, &rt) || | |
410 !dict->GetStringWithoutPathExpansion(kOAuth2AccessTokenKey, &at) || | |
411 !dict->GetIntegerWithoutPathExpansion(kOAuth2ExpiresInKey, &exp)) { | |
412 return false; | |
413 } | |
414 | |
415 refresh_token->assign(rt); | |
416 access_token->assign(at); | |
417 *expires_in_secs = exp; | |
418 return true; | |
419 } | |
420 | |
421 // static | |
422 bool GaiaAuthFetcher::ParseClientLoginToOAuth2Cookie(const std::string& cookie, | |
423 std::string* auth_code) { | |
424 std::vector<std::string> parts; | |
425 base::SplitString(cookie, ';', &parts); | |
426 // Per documentation, the cookie should have Secure and HttpOnly. | |
427 if (!CookiePartsContains(parts, kClientLoginToOAuth2CookiePartSecure) || | |
428 !CookiePartsContains(parts, kClientLoginToOAuth2CookiePartHttpOnly)) { | |
429 return false; | |
430 } | |
431 | |
432 std::vector<std::string>::const_iterator iter; | |
433 for (iter = parts.begin(); iter != parts.end(); ++iter) { | |
434 const std::string& part = *iter; | |
435 if (StartsWithASCII( | |
436 part, kClientLoginToOAuth2CookiePartCodePrefix, false)) { | |
437 auth_code->assign(part.substr( | |
438 kClientLoginToOAuth2CookiePartCodePrefixLength)); | |
439 return true; | |
440 } | |
441 } | |
442 return false; | |
443 } | |
444 | |
445 void GaiaAuthFetcher::StartClientLogin( | 296 void GaiaAuthFetcher::StartClientLogin( |
446 const std::string& username, | 297 const std::string& username, |
447 const std::string& password, | 298 const std::string& password, |
448 const char* const service, | 299 const char* const service, |
449 const std::string& login_token, | 300 const std::string& login_token, |
450 const std::string& login_captcha, | 301 const std::string& login_captcha, |
451 HostedAccountsSetting allow_hosted_accounts) { | 302 HostedAccountsSetting allow_hosted_accounts) { |
452 | 303 |
453 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 304 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
454 | 305 |
455 // This class is thread agnostic, so be sure to call this only on the | 306 // This class is thread agnostic, so be sure to call this only on the |
456 // same thread each time. | 307 // same thread each time. |
457 DVLOG(1) << "Starting new ClientLogin fetch for:" << username; | 308 DVLOG(1) << "Starting new ClientLogin fetch for:" << username; |
458 | 309 |
459 // Must outlive fetcher_. | 310 // Must outlive fetcher_. |
460 request_body_ = MakeClientLoginBody(username, | 311 request_body_ = MakeClientLoginBody(username, |
461 password, | 312 password, |
462 source_, | 313 source_, |
463 service, | 314 service, |
464 login_token, | 315 login_token, |
465 login_captcha, | 316 login_captcha, |
466 allow_hosted_accounts); | 317 allow_hosted_accounts); |
467 fetcher_.reset(CreateGaiaFetcher(getter_, | 318 fetcher_.reset(CreateGaiaFetcher(getter_, |
468 request_body_, | 319 request_body_, |
469 "", | |
470 client_login_gurl_, | 320 client_login_gurl_, |
471 false, | 321 false, |
472 this)); | 322 this)); |
473 fetch_pending_ = true; | 323 fetch_pending_ = true; |
474 fetcher_->Start(); | 324 fetcher_->Start(); |
475 } | 325 } |
476 | 326 |
477 void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid, | 327 void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid, |
478 const std::string& lsid, | 328 const std::string& lsid, |
479 const char* const service) { | 329 const char* const service) { |
480 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 330 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
481 | 331 |
482 DVLOG(1) << "Starting IssueAuthToken for: " << service; | 332 DVLOG(1) << "Starting IssueAuthToken for: " << service; |
483 requested_service_ = service; | 333 requested_service_ = service; |
484 request_body_ = MakeIssueAuthTokenBody(sid, lsid, service); | 334 request_body_ = MakeIssueAuthTokenBody(sid, lsid, service); |
485 fetcher_.reset(CreateGaiaFetcher(getter_, | 335 fetcher_.reset(CreateGaiaFetcher(getter_, |
486 request_body_, | 336 request_body_, |
487 "", | |
488 issue_auth_token_gurl_, | 337 issue_auth_token_gurl_, |
489 false, | 338 false, |
490 this)); | 339 this)); |
491 fetch_pending_ = true; | 340 fetch_pending_ = true; |
492 fetcher_->Start(); | 341 fetcher_->Start(); |
493 } | 342 } |
494 | 343 |
495 void GaiaAuthFetcher::StartOAuthLoginTokenFetch( | |
496 const std::string& auth_token) { | |
497 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | |
498 | |
499 DVLOG(1) << "Starting OAuth login token fetch"; | |
500 request_body_ = MakeGetAuthCodeBody(); | |
501 fetcher_.reset(CreateGaiaFetcher(getter_, | |
502 request_body_, | |
503 MakeGetAuthCodeHeader(auth_token), | |
504 client_login_to_oauth2_gurl_, | |
505 false, | |
506 this)); | |
507 fetch_pending_ = true; | |
508 fetcher_->Start(); | |
509 } | |
510 | |
511 void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, | 344 void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, |
512 const std::string& info_key) { | 345 const std::string& info_key) { |
513 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 346 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
514 | 347 |
515 DVLOG(1) << "Starting GetUserInfo for lsid=" << lsid; | 348 DVLOG(1) << "Starting GetUserInfo for lsid=" << lsid; |
516 request_body_ = MakeGetUserInfoBody(lsid); | 349 request_body_ = MakeGetUserInfoBody(lsid); |
517 fetcher_.reset(CreateGaiaFetcher(getter_, | 350 fetcher_.reset(CreateGaiaFetcher(getter_, |
518 request_body_, | 351 request_body_, |
519 "", | |
520 get_user_info_gurl_, | 352 get_user_info_gurl_, |
521 false, | 353 false, |
522 this)); | 354 this)); |
523 fetch_pending_ = true; | 355 fetch_pending_ = true; |
524 requested_info_key_ = info_key; | 356 requested_info_key_ = info_key; |
525 fetcher_->Start(); | 357 fetcher_->Start(); |
526 } | 358 } |
527 | 359 |
528 void GaiaAuthFetcher::StartTokenAuth(const std::string& auth_token) { | 360 void GaiaAuthFetcher::StartTokenAuth(const std::string& auth_token) { |
529 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 361 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
530 | 362 |
531 DVLOG(1) << "Starting TokenAuth with auth_token=" << auth_token; | 363 DVLOG(1) << "Starting TokenAuth with auth_token=" << auth_token; |
532 | 364 |
533 // The continue URL is a required parameter of the TokenAuth API, but in this | 365 // The continue URL is a required parameter of the TokenAuth API, but in this |
534 // case we don't actually need or want to navigate to it. Setting it to | 366 // case we don't actually need or want to navigate to it. Setting it to |
535 // an arbitrary Google URL. | 367 // an arbitrary Google URL. |
536 std::string continue_url("http://www.google.com"); | 368 std::string continue_url("http://www.google.com"); |
537 request_body_ = MakeTokenAuthBody(auth_token, continue_url, source_); | 369 request_body_ = MakeTokenAuthBody(auth_token, continue_url, source_); |
538 fetcher_.reset(CreateGaiaFetcher(getter_, | 370 fetcher_.reset(CreateGaiaFetcher(getter_, |
539 request_body_, | 371 request_body_, |
540 "", | |
541 token_auth_gurl_, | 372 token_auth_gurl_, |
542 false, | 373 false, |
543 this)); | 374 this)); |
544 fetch_pending_ = true; | 375 fetch_pending_ = true; |
545 fetcher_->Start(); | 376 fetcher_->Start(); |
546 } | 377 } |
547 | 378 |
548 void GaiaAuthFetcher::StartMergeSession(const std::string& auth_token) { | 379 void GaiaAuthFetcher::StartMergeSession(const std::string& auth_token) { |
549 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 380 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
550 | 381 |
551 DVLOG(1) << "Starting MergeSession with auth_token=" << auth_token; | 382 DVLOG(1) << "Starting MergeSession with auth_token=" << auth_token; |
552 | 383 |
553 // The continue URL is a required parameter of the MergeSession API, but in | 384 // The continue URL is a required parameter of the MergeSession API, but in |
554 // this case we don't actually need or want to navigate to it. Setting it to | 385 // this case we don't actually need or want to navigate to it. Setting it to |
555 // an arbitrary Google URL. | 386 // an arbitrary Google URL. |
556 // | 387 // |
557 // In order for the new session to be merged correctly, the server needs to | 388 // In order for the new session to be merged correctly, the server needs to |
558 // know what sessions already exist in the browser. The fetcher needs to be | 389 // know what sessions already exist in the browser. The fetcher needs to be |
559 // created such that it sends the cookies with the request, which is | 390 // created such that it sends the cookies with the request, which is |
560 // different from all other requests the fetcher can make. | 391 // different from all other requests the fetcher can make. |
561 std::string continue_url("http://www.google.com"); | 392 std::string continue_url("http://www.google.com"); |
562 request_body_ = MakeMergeSessionBody(auth_token, continue_url, source_); | 393 request_body_ = MakeMergeSessionBody(auth_token, continue_url, source_); |
563 fetcher_.reset(CreateGaiaFetcher(getter_, | 394 fetcher_.reset(CreateGaiaFetcher(getter_, |
564 request_body_, | 395 request_body_, |
565 "", | |
566 merge_session_gurl_, | 396 merge_session_gurl_, |
567 true, | 397 true, |
568 this)); | 398 this)); |
569 fetch_pending_ = true; | 399 fetch_pending_ = true; |
570 fetcher_->Start(); | 400 fetcher_->Start(); |
571 } | 401 } |
572 | 402 |
573 // static | 403 // static |
574 GoogleServiceAuthError GaiaAuthFetcher::GenerateAuthError( | 404 GoogleServiceAuthError GaiaAuthFetcher::GenerateAuthError( |
575 const std::string& data, | 405 const std::string& data, |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
699 if (status.is_success() && response_code == RC_REQUEST_OK) { | 529 if (status.is_success() && response_code == RC_REQUEST_OK) { |
700 // Only the bare token is returned in the body of this Gaia call | 530 // Only the bare token is returned in the body of this Gaia call |
701 // without any padding. | 531 // without any padding. |
702 consumer_->OnIssueAuthTokenSuccess(requested_service_, data); | 532 consumer_->OnIssueAuthTokenSuccess(requested_service_, data); |
703 } else { | 533 } else { |
704 consumer_->OnIssueAuthTokenFailure(requested_service_, | 534 consumer_->OnIssueAuthTokenFailure(requested_service_, |
705 GenerateAuthError(data, status)); | 535 GenerateAuthError(data, status)); |
706 } | 536 } |
707 } | 537 } |
708 | 538 |
709 void GaiaAuthFetcher::OnClientLoginToOAuth2Fetched( | |
710 const std::string& data, | |
711 const net::ResponseCookies& cookies, | |
712 const net::URLRequestStatus& status, | |
713 int response_code) { | |
714 if (status.is_success() && response_code == RC_REQUEST_OK) { | |
715 std::string auth_code; | |
716 if (!ParseClientLoginToOAuth2Response(cookies, &auth_code)) { | |
717 consumer_->OnOAuthLoginTokenFailure(GoogleServiceAuthError( | |
718 GoogleServiceAuthError::UNEXPECTED_RESPONSE)); | |
719 } else { | |
720 // Start GetTokenPair. | |
721 StartOAuth2TokenPairFetch(auth_code); | |
722 } | |
723 } else { | |
724 consumer_->OnOAuthLoginTokenFailure(GenerateAuthError(data, status)); | |
725 } | |
726 } | |
727 | |
728 void GaiaAuthFetcher::StartOAuth2TokenPairFetch(const std::string& auth_code) { | |
729 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | |
730 | |
731 DVLOG(1) << "Starting OAuth token pair fetch"; | |
732 request_body_ = MakeGetTokenPairBody(auth_code); | |
733 fetcher_.reset(CreateGaiaFetcher(getter_, | |
734 request_body_, | |
735 "", | |
736 oauth2_token_gurl_, | |
737 false, | |
738 this)); | |
739 fetch_pending_ = true; | |
740 fetcher_->Start(); | |
741 } | |
742 | |
743 void GaiaAuthFetcher::OnOAuth2TokenPairFetched( | |
744 const std::string& data, | |
745 const net::URLRequestStatus& status, | |
746 int response_code) { | |
747 if (status.is_success() && response_code == RC_REQUEST_OK) { | |
748 std::string refresh_token; | |
749 std::string access_token; | |
750 int expires_in_secs; | |
751 if (ParseOAuth2TokenPairResponse( | |
752 data, &refresh_token, &access_token, &expires_in_secs)) { | |
753 consumer_->OnOAuthLoginTokenSuccess( | |
754 refresh_token, access_token, expires_in_secs); | |
755 } else { | |
756 consumer_->OnOAuthLoginTokenFailure(GoogleServiceAuthError( | |
757 GoogleServiceAuthError::UNEXPECTED_RESPONSE)); | |
758 } | |
759 } else { | |
760 consumer_->OnOAuthLoginTokenFailure(GenerateAuthError(data, status)); | |
761 } | |
762 } | |
763 | |
764 void GaiaAuthFetcher::OnGetUserInfoFetched( | 539 void GaiaAuthFetcher::OnGetUserInfoFetched( |
765 const std::string& data, | 540 const std::string& data, |
766 const net::URLRequestStatus& status, | 541 const net::URLRequestStatus& status, |
767 int response_code) { | 542 int response_code) { |
768 using std::vector; | 543 using std::vector; |
769 using std::string; | 544 using std::string; |
770 using std::pair; | 545 using std::pair; |
771 | 546 |
772 if (status.is_success() && response_code == RC_REQUEST_OK) { | 547 if (status.is_success() && response_code == RC_REQUEST_OK) { |
773 vector<pair<string, string> > tokens; | 548 vector<pair<string, string> > tokens; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 fetch_pending_ = false; | 584 fetch_pending_ = false; |
810 const GURL& url = source->GetURL(); | 585 const GURL& url = source->GetURL(); |
811 const net::URLRequestStatus& status = source->GetStatus(); | 586 const net::URLRequestStatus& status = source->GetStatus(); |
812 int response_code = source->GetResponseCode(); | 587 int response_code = source->GetResponseCode(); |
813 std::string data; | 588 std::string data; |
814 source->GetResponseAsString(&data); | 589 source->GetResponseAsString(&data); |
815 if (url == client_login_gurl_) { | 590 if (url == client_login_gurl_) { |
816 OnClientLoginFetched(data, status, response_code); | 591 OnClientLoginFetched(data, status, response_code); |
817 } else if (url == issue_auth_token_gurl_) { | 592 } else if (url == issue_auth_token_gurl_) { |
818 OnIssueAuthTokenFetched(data, status, response_code); | 593 OnIssueAuthTokenFetched(data, status, response_code); |
819 } else if (url == client_login_to_oauth2_gurl_) { | |
820 OnClientLoginToOAuth2Fetched( | |
821 data, source->GetCookies(), status, response_code); | |
822 } else if (url == oauth2_token_gurl_) { | |
823 OnOAuth2TokenPairFetched(data, status, response_code); | |
824 } else if (url == get_user_info_gurl_) { | 594 } else if (url == get_user_info_gurl_) { |
825 OnGetUserInfoFetched(data, status, response_code); | 595 OnGetUserInfoFetched(data, status, response_code); |
826 } else if (url == token_auth_gurl_) { | 596 } else if (url == token_auth_gurl_) { |
827 OnTokenAuthFetched(data, status, response_code); | 597 OnTokenAuthFetched(data, status, response_code); |
828 } else if (url == merge_session_gurl_ || | 598 } else if (url == merge_session_gurl_ || |
829 (source && source->GetOriginalURL() == merge_session_gurl_)) { | 599 (source && source->GetOriginalURL() == merge_session_gurl_)) { |
830 // MergeSession may redirect, so check the original URL of the fetcher. | 600 // MergeSession may redirect, so check the original URL of the fetcher. |
831 OnMergeSessionFetched(data, status, response_code); | 601 OnMergeSessionFetched(data, status, response_code); |
832 } else { | 602 } else { |
833 NOTREACHED(); | 603 NOTREACHED(); |
834 } | 604 } |
835 } | 605 } |
836 | 606 |
837 // static | 607 // static |
838 bool GaiaAuthFetcher::IsSecondFactorSuccess( | 608 bool GaiaAuthFetcher::IsSecondFactorSuccess( |
839 const std::string& alleged_error) { | 609 const std::string& alleged_error) { |
840 return alleged_error.find(kSecondFactor) != | 610 return alleged_error.find(kSecondFactor) != |
841 std::string::npos; | 611 std::string::npos; |
842 } | 612 } |
OLD | NEW |