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 <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 "service=%s&" | 47 "service=%s&" |
48 "Session=%s"; | 48 "Session=%s"; |
49 // static | 49 // static |
50 const char GaiaAuthFetcher::kGetUserInfoFormat[] = | 50 const char GaiaAuthFetcher::kGetUserInfoFormat[] = |
51 "LSID=%s"; | 51 "LSID=%s"; |
52 // static | 52 // static |
53 const char GaiaAuthFetcher::kTokenAuthFormat[] = | 53 const char GaiaAuthFetcher::kTokenAuthFormat[] = |
54 "auth=%s&" | 54 "auth=%s&" |
55 "continue=%s&" | 55 "continue=%s&" |
56 "source=%s"; | 56 "source=%s"; |
| 57 // static |
| 58 const char GaiaAuthFetcher::kMergeSessionFormat[] = |
| 59 "uberauth=%s&" |
| 60 "continue=%s&" |
| 61 "source=%s"; |
57 | 62 |
58 // static | 63 // static |
59 const char GaiaAuthFetcher::kAccountDeletedError[] = "AccountDeleted"; | 64 const char GaiaAuthFetcher::kAccountDeletedError[] = "AccountDeleted"; |
60 const char GaiaAuthFetcher::kAccountDeletedErrorCode[] = "adel"; | 65 const char GaiaAuthFetcher::kAccountDeletedErrorCode[] = "adel"; |
61 // static | 66 // static |
62 const char GaiaAuthFetcher::kAccountDisabledError[] = "AccountDisabled"; | 67 const char GaiaAuthFetcher::kAccountDisabledError[] = "AccountDisabled"; |
63 const char GaiaAuthFetcher::kAccountDisabledErrorCode[] = "adis"; | 68 const char GaiaAuthFetcher::kAccountDisabledErrorCode[] = "adis"; |
64 // static | 69 // static |
65 const char GaiaAuthFetcher::kBadAuthenticationError[] = "BadAuthentication"; | 70 const char GaiaAuthFetcher::kBadAuthenticationError[] = "BadAuthentication"; |
66 const char GaiaAuthFetcher::kBadAuthenticationErrorCode[] = "badauth"; | 71 const char GaiaAuthFetcher::kBadAuthenticationErrorCode[] = "badauth"; |
(...skipping 30 matching lines...) Expand all Loading... |
97 GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer, | 102 GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer, |
98 const std::string& source, | 103 const std::string& source, |
99 net::URLRequestContextGetter* getter) | 104 net::URLRequestContextGetter* getter) |
100 : consumer_(consumer), | 105 : consumer_(consumer), |
101 getter_(getter), | 106 getter_(getter), |
102 source_(source), | 107 source_(source), |
103 client_login_gurl_(GaiaUrls::GetInstance()->client_login_url()), | 108 client_login_gurl_(GaiaUrls::GetInstance()->client_login_url()), |
104 issue_auth_token_gurl_(GaiaUrls::GetInstance()->issue_auth_token_url()), | 109 issue_auth_token_gurl_(GaiaUrls::GetInstance()->issue_auth_token_url()), |
105 get_user_info_gurl_(GaiaUrls::GetInstance()->get_user_info_url()), | 110 get_user_info_gurl_(GaiaUrls::GetInstance()->get_user_info_url()), |
106 token_auth_gurl_(GaiaUrls::GetInstance()->token_auth_url()), | 111 token_auth_gurl_(GaiaUrls::GetInstance()->token_auth_url()), |
| 112 merge_session_gurl_(GaiaUrls::GetInstance()->merge_session_url()), |
107 fetch_pending_(false) {} | 113 fetch_pending_(false) {} |
108 | 114 |
109 GaiaAuthFetcher::~GaiaAuthFetcher() {} | 115 GaiaAuthFetcher::~GaiaAuthFetcher() {} |
110 | 116 |
111 bool GaiaAuthFetcher::HasPendingFetch() { | 117 bool GaiaAuthFetcher::HasPendingFetch() { |
112 return fetch_pending_; | 118 return fetch_pending_; |
113 } | 119 } |
114 | 120 |
115 void GaiaAuthFetcher::CancelRequest() { | 121 void GaiaAuthFetcher::CancelRequest() { |
116 fetcher_.reset(); | 122 fetcher_.reset(); |
117 fetch_pending_ = false; | 123 fetch_pending_ = false; |
118 } | 124 } |
119 | 125 |
120 // static | 126 // static |
121 URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( | 127 URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( |
122 net::URLRequestContextGetter* getter, | 128 net::URLRequestContextGetter* getter, |
123 const std::string& body, | 129 const std::string& body, |
124 const GURL& gaia_gurl, | 130 const GURL& gaia_gurl, |
| 131 bool send_cookies, |
125 URLFetcher::Delegate* delegate) { | 132 URLFetcher::Delegate* delegate) { |
126 | 133 |
127 URLFetcher* to_return = | 134 URLFetcher* to_return = |
128 URLFetcher::Create(0, | 135 URLFetcher::Create(0, |
129 gaia_gurl, | 136 gaia_gurl, |
130 URLFetcher::POST, | 137 URLFetcher::POST, |
131 delegate); | 138 delegate); |
132 to_return->set_request_context(getter); | 139 to_return->set_request_context(getter); |
133 to_return->set_load_flags(net::LOAD_DO_NOT_SEND_COOKIES); | |
134 to_return->set_upload_data("application/x-www-form-urlencoded", body); | 140 to_return->set_upload_data("application/x-www-form-urlencoded", body); |
| 141 |
| 142 // The Gaia token exchange requests do not require any cookie-based |
| 143 // identification as part of requests. We suppress sending any cookies to |
| 144 // maintain a separation between the user's browsing and Chrome's internal |
| 145 // services. Where such mixing is desired (MergeSession), it will be done |
| 146 // explicitly. |
| 147 if (!send_cookies) |
| 148 to_return->set_load_flags(net::LOAD_DO_NOT_SEND_COOKIES); |
| 149 |
135 return to_return; | 150 return to_return; |
136 } | 151 } |
137 | 152 |
138 // static | 153 // static |
139 std::string GaiaAuthFetcher::MakeClientLoginBody( | 154 std::string GaiaAuthFetcher::MakeClientLoginBody( |
140 const std::string& username, | 155 const std::string& username, |
141 const std::string& password, | 156 const std::string& password, |
142 const std::string& source, | 157 const std::string& source, |
143 const char* service, | 158 const char* service, |
144 const std::string& login_token, | 159 const std::string& login_token, |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 const std::string& source) { | 221 const std::string& source) { |
207 std::string encoded_auth_token = EscapeUrlEncodedData(auth_token, true); | 222 std::string encoded_auth_token = EscapeUrlEncodedData(auth_token, true); |
208 std::string encoded_continue_url = EscapeUrlEncodedData(continue_url, true); | 223 std::string encoded_continue_url = EscapeUrlEncodedData(continue_url, true); |
209 std::string encoded_source = EscapeUrlEncodedData(source, true); | 224 std::string encoded_source = EscapeUrlEncodedData(source, true); |
210 return base::StringPrintf(kTokenAuthFormat, | 225 return base::StringPrintf(kTokenAuthFormat, |
211 encoded_auth_token.c_str(), | 226 encoded_auth_token.c_str(), |
212 encoded_continue_url.c_str(), | 227 encoded_continue_url.c_str(), |
213 encoded_source.c_str()); | 228 encoded_source.c_str()); |
214 } | 229 } |
215 | 230 |
| 231 // static |
| 232 std::string GaiaAuthFetcher::MakeMergeSessionBody( |
| 233 const std::string& auth_token, |
| 234 const std::string& continue_url, |
| 235 const std::string& source) { |
| 236 std::string encoded_auth_token = EscapeUrlEncodedData(auth_token, true); |
| 237 std::string encoded_continue_url = EscapeUrlEncodedData(continue_url, true); |
| 238 std::string encoded_source = EscapeUrlEncodedData(source, true); |
| 239 return base::StringPrintf(kMergeSessionFormat, |
| 240 encoded_auth_token.c_str(), |
| 241 encoded_continue_url.c_str(), |
| 242 encoded_source.c_str()); |
| 243 } |
| 244 |
216 // Helper method that extracts tokens from a successful reply. | 245 // Helper method that extracts tokens from a successful reply. |
217 // static | 246 // static |
218 void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data, | 247 void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data, |
219 std::string* sid, | 248 std::string* sid, |
220 std::string* lsid, | 249 std::string* lsid, |
221 std::string* token) { | 250 std::string* token) { |
222 using std::vector; | 251 using std::vector; |
223 using std::pair; | 252 using std::pair; |
224 using std::string; | 253 using std::string; |
225 | 254 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 request_body_ = MakeClientLoginBody(username, | 310 request_body_ = MakeClientLoginBody(username, |
282 password, | 311 password, |
283 source_, | 312 source_, |
284 service, | 313 service, |
285 login_token, | 314 login_token, |
286 login_captcha, | 315 login_captcha, |
287 allow_hosted_accounts); | 316 allow_hosted_accounts); |
288 fetcher_.reset(CreateGaiaFetcher(getter_, | 317 fetcher_.reset(CreateGaiaFetcher(getter_, |
289 request_body_, | 318 request_body_, |
290 client_login_gurl_, | 319 client_login_gurl_, |
| 320 false, |
291 this)); | 321 this)); |
292 fetch_pending_ = true; | 322 fetch_pending_ = true; |
293 fetcher_->Start(); | 323 fetcher_->Start(); |
294 } | 324 } |
295 | 325 |
296 void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid, | 326 void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid, |
297 const std::string& lsid, | 327 const std::string& lsid, |
298 const char* const service) { | 328 const char* const service) { |
299 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 329 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
300 | 330 |
301 VLOG(1) << "Starting IssueAuthToken for: " << service; | 331 VLOG(1) << "Starting IssueAuthToken for: " << service; |
302 requested_service_ = service; | 332 requested_service_ = service; |
303 request_body_ = MakeIssueAuthTokenBody(sid, lsid, service); | 333 request_body_ = MakeIssueAuthTokenBody(sid, lsid, service); |
304 fetcher_.reset(CreateGaiaFetcher(getter_, | 334 fetcher_.reset(CreateGaiaFetcher(getter_, |
305 request_body_, | 335 request_body_, |
306 issue_auth_token_gurl_, | 336 issue_auth_token_gurl_, |
| 337 false, |
307 this)); | 338 this)); |
308 fetch_pending_ = true; | 339 fetch_pending_ = true; |
309 fetcher_->Start(); | 340 fetcher_->Start(); |
310 } | 341 } |
311 | 342 |
312 void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, | 343 void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, |
313 const std::string& info_key) { | 344 const std::string& info_key) { |
314 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 345 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
315 | 346 |
316 VLOG(1) << "Starting GetUserInfo for lsid=" << lsid; | 347 VLOG(1) << "Starting GetUserInfo for lsid=" << lsid; |
317 request_body_ = MakeGetUserInfoBody(lsid); | 348 request_body_ = MakeGetUserInfoBody(lsid); |
318 fetcher_.reset(CreateGaiaFetcher(getter_, | 349 fetcher_.reset(CreateGaiaFetcher(getter_, |
319 request_body_, | 350 request_body_, |
320 get_user_info_gurl_, | 351 get_user_info_gurl_, |
| 352 false, |
321 this)); | 353 this)); |
322 fetch_pending_ = true; | 354 fetch_pending_ = true; |
323 requested_info_key_ = info_key; | 355 requested_info_key_ = info_key; |
324 fetcher_->Start(); | 356 fetcher_->Start(); |
325 } | 357 } |
326 | 358 |
327 void GaiaAuthFetcher::StartTokenAuth(const std::string& auth_token) { | 359 void GaiaAuthFetcher::StartTokenAuth(const std::string& auth_token) { |
328 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 360 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
329 | 361 |
330 VLOG(1) << "Starting TokenAuth with auth_token=" << auth_token; | 362 VLOG(1) << "Starting TokenAuth with auth_token=" << auth_token; |
331 | 363 |
332 // The continue URL is a required parameter of the TokenAuth API, but in this | 364 // The continue URL is a required parameter of the TokenAuth API, but in this |
333 // case we don't actually need or want to navigate to it. Setting it to | 365 // case we don't actually need or want to navigate to it. Setting it to |
334 // an arbitrary Google URL. | 366 // an arbitrary Google URL. |
335 std::string continue_url("http://www.google.com"); | 367 std::string continue_url("http://www.google.com"); |
336 request_body_ = MakeTokenAuthBody(auth_token, continue_url, source_); | 368 request_body_ = MakeTokenAuthBody(auth_token, continue_url, source_); |
337 fetcher_.reset(CreateGaiaFetcher(getter_, | 369 fetcher_.reset(CreateGaiaFetcher(getter_, |
338 request_body_, | 370 request_body_, |
339 token_auth_gurl_, | 371 token_auth_gurl_, |
| 372 false, |
| 373 this)); |
| 374 fetch_pending_ = true; |
| 375 fetcher_->Start(); |
| 376 } |
| 377 |
| 378 void GaiaAuthFetcher::StartMergeSession(const std::string& auth_token) { |
| 379 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
| 380 |
| 381 VLOG(1) << "Starting MergeSession with auth_token=" << auth_token; |
| 382 |
| 383 // The continue URL is a required parameter of the MergeSession API, but in |
| 384 // this case we don't actually need or want to navigate to it. Setting it to |
| 385 // an arbitrary Google URL. |
| 386 // |
| 387 // In order for the new session to be merged correctly, the server needs to |
| 388 // know what sessions already exist in the browser. The fetcher needs to be |
| 389 // created such that it sends the cookies with the request, which is |
| 390 // different from all other requests the fetcher can make. |
| 391 std::string continue_url("http://www.google.com"); |
| 392 request_body_ = MakeMergeSessionBody(auth_token, continue_url, source_); |
| 393 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 394 request_body_, |
| 395 merge_session_gurl_, |
| 396 true, |
340 this)); | 397 this)); |
341 fetch_pending_ = true; | 398 fetch_pending_ = true; |
342 fetcher_->Start(); | 399 fetcher_->Start(); |
343 } | 400 } |
344 | 401 |
345 // static | 402 // static |
346 GoogleServiceAuthError GaiaAuthFetcher::GenerateAuthError( | 403 GoogleServiceAuthError GaiaAuthFetcher::GenerateAuthError( |
347 const std::string& data, | 404 const std::string& data, |
348 const net::URLRequestStatus& status) { | 405 const net::URLRequestStatus& status) { |
349 if (!status.is_success()) { | 406 if (!status.is_success()) { |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 void GaiaAuthFetcher::OnTokenAuthFetched(const std::string& data, | 562 void GaiaAuthFetcher::OnTokenAuthFetched(const std::string& data, |
506 const net::URLRequestStatus& status, | 563 const net::URLRequestStatus& status, |
507 int response_code) { | 564 int response_code) { |
508 if (status.is_success() && response_code == RC_REQUEST_OK) { | 565 if (status.is_success() && response_code == RC_REQUEST_OK) { |
509 consumer_->OnTokenAuthSuccess(data); | 566 consumer_->OnTokenAuthSuccess(data); |
510 } else { | 567 } else { |
511 consumer_->OnTokenAuthFailure(GenerateAuthError(data, status)); | 568 consumer_->OnTokenAuthFailure(GenerateAuthError(data, status)); |
512 } | 569 } |
513 } | 570 } |
514 | 571 |
| 572 void GaiaAuthFetcher::OnMergeSessionFetched(const std::string& data, |
| 573 const net::URLRequestStatus& status, |
| 574 int response_code) { |
| 575 if (status.is_success() && response_code == RC_REQUEST_OK) { |
| 576 consumer_->OnMergeSessionSuccess(data); |
| 577 } else { |
| 578 consumer_->OnMergeSessionFailure(GenerateAuthError(data, status)); |
| 579 } |
| 580 } |
| 581 |
515 void GaiaAuthFetcher::OnURLFetchComplete(const URLFetcher* source, | 582 void GaiaAuthFetcher::OnURLFetchComplete(const URLFetcher* source, |
516 const GURL& url, | 583 const GURL& url, |
517 const net::URLRequestStatus& status, | 584 const net::URLRequestStatus& status, |
518 int response_code, | 585 int response_code, |
519 const net::ResponseCookies& cookies, | 586 const net::ResponseCookies& cookies, |
520 const std::string& data) { | 587 const std::string& data) { |
521 fetch_pending_ = false; | 588 fetch_pending_ = false; |
522 if (url == client_login_gurl_) { | 589 if (url == client_login_gurl_) { |
523 OnClientLoginFetched(data, status, response_code); | 590 OnClientLoginFetched(data, status, response_code); |
524 } else if (url == issue_auth_token_gurl_) { | 591 } else if (url == issue_auth_token_gurl_) { |
525 OnIssueAuthTokenFetched(data, status, response_code); | 592 OnIssueAuthTokenFetched(data, status, response_code); |
526 } else if (url == get_user_info_gurl_) { | 593 } else if (url == get_user_info_gurl_) { |
527 OnGetUserInfoFetched(data, status, response_code); | 594 OnGetUserInfoFetched(data, status, response_code); |
528 } else if (url == token_auth_gurl_) { | 595 } else if (url == token_auth_gurl_) { |
529 OnTokenAuthFetched(data, status, response_code); | 596 OnTokenAuthFetched(data, status, response_code); |
| 597 } else if (url == merge_session_gurl_ || |
| 598 (source && source->original_url() == merge_session_gurl_)) { |
| 599 // MergeSession may redirect, so check the original URL of the fetcher. |
| 600 OnMergeSessionFetched(data, status, response_code); |
530 } else { | 601 } else { |
531 NOTREACHED(); | 602 NOTREACHED(); |
532 } | 603 } |
533 } | 604 } |
534 | 605 |
535 // static | 606 // static |
536 bool GaiaAuthFetcher::IsSecondFactorSuccess( | 607 bool GaiaAuthFetcher::IsSecondFactorSuccess( |
537 const std::string& alleged_error) { | 608 const std::string& alleged_error) { |
538 return alleged_error.find(kSecondFactor) != | 609 return alleged_error.find(kSecondFactor) != |
539 std::string::npos; | 610 std::string::npos; |
540 } | 611 } |
OLD | NEW |