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