OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "google_apis/gaia/gaia_auth_fetcher.h" | 5 #include "google_apis/gaia/gaia_auth_fetcher.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/json/json_reader.h" | 12 #include "base/json/json_reader.h" |
13 #include "base/json/json_writer.h" | 13 #include "base/json/json_writer.h" |
14 #include "base/string_split.h" | 14 #include "base/string_split.h" |
15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
16 #include "base/stringprintf.h" | 16 #include "base/stringprintf.h" |
17 #include "base/values.h" | 17 #include "base/values.h" |
18 #include "google_apis/gaia/gaia_auth_consumer.h" | 18 #include "google_apis/gaia/gaia_auth_consumer.h" |
19 #include "google_apis/gaia/gaia_constants.h" | 19 #include "google_apis/gaia/gaia_constants.h" |
20 #include "google_apis/gaia/gaia_urls.h" | 20 #include "google_apis/gaia/gaia_urls.h" |
21 #include "google_apis/gaia/google_service_auth_error.h" | 21 #include "google_apis/gaia/google_service_auth_error.h" |
22 #include "net/base/escape.h" | 22 #include "net/base/escape.h" |
23 #include "net/base/load_flags.h" | 23 #include "net/base/load_flags.h" |
| 24 #include "net/http/http_response_headers.h" |
24 #include "net/http/http_status_code.h" | 25 #include "net/http/http_status_code.h" |
25 #include "net/url_request/url_fetcher.h" | 26 #include "net/url_request/url_fetcher.h" |
26 #include "net/url_request/url_request_context_getter.h" | 27 #include "net/url_request/url_request_context_getter.h" |
27 #include "net/url_request/url_request_status.h" | 28 #include "net/url_request/url_request_status.h" |
28 | 29 |
29 namespace { | 30 namespace { |
30 const int kLoadFlagsIgnoreCookies = net::LOAD_DO_NOT_SEND_COOKIES | | 31 const int kLoadFlagsIgnoreCookies = net::LOAD_DO_NOT_SEND_COOKIES | |
31 net::LOAD_DO_NOT_SAVE_COOKIES; | 32 net::LOAD_DO_NOT_SAVE_COOKIES; |
32 | 33 |
33 static bool CookiePartsContains(const std::vector<std::string>& parts, | 34 static bool CookiePartsContains(const std::vector<std::string>& parts, |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 | 150 |
150 // static | 151 // static |
151 const char GaiaAuthFetcher::kSecondFactor[] = "Info=InvalidSecondFactor"; | 152 const char GaiaAuthFetcher::kSecondFactor[] = "Info=InvalidSecondFactor"; |
152 | 153 |
153 // static | 154 // static |
154 const char GaiaAuthFetcher::kAuthHeaderFormat[] = | 155 const char GaiaAuthFetcher::kAuthHeaderFormat[] = |
155 "Authorization: GoogleLogin auth=%s"; | 156 "Authorization: GoogleLogin auth=%s"; |
156 // static | 157 // static |
157 const char GaiaAuthFetcher::kOAuthHeaderFormat[] = "Authorization: OAuth %s"; | 158 const char GaiaAuthFetcher::kOAuthHeaderFormat[] = "Authorization: OAuth %s"; |
158 // static | 159 // static |
| 160 const char GaiaAuthFetcher::kOAuth2BearerHeaderFormat[] = |
| 161 "Authorization: Bearer %s"; |
| 162 // static |
159 const char GaiaAuthFetcher::kClientLoginToOAuth2CookiePartSecure[] = "Secure"; | 163 const char GaiaAuthFetcher::kClientLoginToOAuth2CookiePartSecure[] = "Secure"; |
160 // static | 164 // static |
161 const char GaiaAuthFetcher::kClientLoginToOAuth2CookiePartHttpOnly[] = | 165 const char GaiaAuthFetcher::kClientLoginToOAuth2CookiePartHttpOnly[] = |
162 "HttpOnly"; | 166 "HttpOnly"; |
163 // static | 167 // static |
164 const char GaiaAuthFetcher::kClientLoginToOAuth2CookiePartCodePrefix[] = | 168 const char GaiaAuthFetcher::kClientLoginToOAuth2CookiePartCodePrefix[] = |
165 "oauth_code="; | 169 "oauth_code="; |
166 // static | 170 // static |
167 const int GaiaAuthFetcher::kClientLoginToOAuth2CookiePartCodePrefixLength = | 171 const int GaiaAuthFetcher::kClientLoginToOAuth2CookiePartCodePrefixLength = |
168 arraysize(GaiaAuthFetcher::kClientLoginToOAuth2CookiePartCodePrefix) - 1; | 172 arraysize(GaiaAuthFetcher::kClientLoginToOAuth2CookiePartCodePrefix) - 1; |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 | 351 |
348 // Helper method that extracts tokens from a successful reply. | 352 // Helper method that extracts tokens from a successful reply. |
349 // static | 353 // static |
350 void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data, | 354 void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data, |
351 std::string* sid, | 355 std::string* sid, |
352 std::string* lsid, | 356 std::string* lsid, |
353 std::string* token) { | 357 std::string* token) { |
354 using std::vector; | 358 using std::vector; |
355 using std::pair; | 359 using std::pair; |
356 using std::string; | 360 using std::string; |
357 | 361 sid->clear(); |
| 362 lsid->clear(); |
| 363 token->clear(); |
358 vector<pair<string, string> > tokens; | 364 vector<pair<string, string> > tokens; |
359 base::SplitStringIntoKeyValuePairs(data, '=', '\n', &tokens); | 365 base::SplitStringIntoKeyValuePairs(data, '=', '\n', &tokens); |
360 for (vector<pair<string, string> >::iterator i = tokens.begin(); | 366 for (vector<pair<string, string> >::iterator i = tokens.begin(); |
361 i != tokens.end(); ++i) { | 367 i != tokens.end(); ++i) { |
362 if (i->first == "SID") { | 368 if (i->first == "SID") { |
363 sid->assign(i->second); | 369 sid->assign(i->second); |
364 } else if (i->first == "LSID") { | 370 } else if (i->first == "LSID") { |
365 lsid->assign(i->second); | 371 lsid->assign(i->second); |
366 } else if (i->first == "Auth") { | 372 } else if (i->first == "Auth") { |
367 token->assign(i->second); | 373 token->assign(i->second); |
368 } | 374 } |
369 } | 375 } |
| 376 // If this was a request for uberauth token, then that's all we've got in |
| 377 // data. |
| 378 if (sid->empty() && lsid->empty() && token->empty()) |
| 379 token->assign(data); |
370 } | 380 } |
371 | 381 |
372 // static | 382 // static |
373 std::string GaiaAuthFetcher::MakeClientOAuthBody( | 383 std::string GaiaAuthFetcher::MakeClientOAuthBody( |
374 const std::string& username, | 384 const std::string& username, |
375 const std::string& password, | 385 const std::string& password, |
376 const std::vector<std::string>& scopes, | 386 const std::vector<std::string>& scopes, |
377 const std::string& persistent_id, | 387 const std::string& persistent_id, |
378 const std::string& friendly_name, | 388 const std::string& friendly_name, |
379 const std::string& locale) { | 389 const std::string& locale) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 std::string json_string; | 437 std::string json_string; |
428 base::JSONWriter::Write(dict.get(), &json_string); | 438 base::JSONWriter::Write(dict.get(), &json_string); |
429 return json_string; | 439 return json_string; |
430 } | 440 } |
431 | 441 |
432 // static | 442 // static |
433 std::string GaiaAuthFetcher::MakeOAuthLoginBody(const std::string& service, | 443 std::string GaiaAuthFetcher::MakeOAuthLoginBody(const std::string& service, |
434 const std::string& source) { | 444 const std::string& source) { |
435 std::string encoded_service = net::EscapeUrlEncodedData(service, true); | 445 std::string encoded_service = net::EscapeUrlEncodedData(service, true); |
436 std::string encoded_source = net::EscapeUrlEncodedData(source, true); | 446 std::string encoded_source = net::EscapeUrlEncodedData(source, true); |
437 return StringPrintf(kOAuthLoginFormat, encoded_service.c_str(), | 447 return StringPrintf(kOAuthLoginFormat, |
| 448 encoded_service.c_str(), |
438 encoded_source.c_str()); | 449 encoded_source.c_str()); |
439 } | 450 } |
440 | 451 |
441 // static | 452 // static |
442 void GaiaAuthFetcher::ParseClientLoginFailure(const std::string& data, | 453 void GaiaAuthFetcher::ParseClientLoginFailure(const std::string& data, |
443 std::string* error, | 454 std::string* error, |
444 std::string* error_url, | 455 std::string* error_url, |
445 std::string* captcha_url, | 456 std::string* captcha_url, |
446 std::string* captcha_token) { | 457 std::string* captcha_token) { |
447 using std::vector; | 458 using std::vector; |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 fetch_pending_ = true; | 774 fetch_pending_ = true; |
764 fetcher_->Start(); | 775 fetcher_->Start(); |
765 } | 776 } |
766 | 777 |
767 void GaiaAuthFetcher::StartOAuthLogin(const std::string& access_token, | 778 void GaiaAuthFetcher::StartOAuthLogin(const std::string& access_token, |
768 const std::string& service) { | 779 const std::string& service) { |
769 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 780 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
770 | 781 |
771 request_body_ = MakeOAuthLoginBody(service, source_); | 782 request_body_ = MakeOAuthLoginBody(service, source_); |
772 std::string authentication_header = | 783 std::string authentication_header = |
773 base::StringPrintf("Authorization: Bearer %s", access_token.c_str()); | 784 base::StringPrintf(kOAuth2BearerHeaderFormat, access_token.c_str()); |
774 fetcher_.reset(CreateGaiaFetcher(getter_, | 785 fetcher_.reset(CreateGaiaFetcher(getter_, |
775 request_body_, | 786 request_body_, |
776 authentication_header, | 787 authentication_header, |
777 oauth_login_gurl_, | 788 oauth_login_gurl_, |
778 kLoadFlagsIgnoreCookies, | 789 kLoadFlagsIgnoreCookies, |
779 this)); | 790 this)); |
780 fetch_pending_ = true; | 791 fetch_pending_ = true; |
781 fetcher_->Start(); | 792 fetcher_->Start(); |
782 } | 793 } |
783 | 794 |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 void GaiaAuthFetcher::OnURLFetchComplete(const net::URLFetcher* source) { | 1076 void GaiaAuthFetcher::OnURLFetchComplete(const net::URLFetcher* source) { |
1066 fetch_pending_ = false; | 1077 fetch_pending_ = false; |
1067 // Some of the GAIA requests perform redirects, which results in the final | 1078 // Some of the GAIA requests perform redirects, which results in the final |
1068 // URL of the fetcher not being the original URL requested. Therefore use | 1079 // URL of the fetcher not being the original URL requested. Therefore use |
1069 // the original URL when determining which OnXXX function to call. | 1080 // the original URL when determining which OnXXX function to call. |
1070 const GURL& url = source->GetOriginalURL(); | 1081 const GURL& url = source->GetOriginalURL(); |
1071 const net::URLRequestStatus& status = source->GetStatus(); | 1082 const net::URLRequestStatus& status = source->GetStatus(); |
1072 int response_code = source->GetResponseCode(); | 1083 int response_code = source->GetResponseCode(); |
1073 std::string data; | 1084 std::string data; |
1074 source->GetResponseAsString(&data); | 1085 source->GetResponseAsString(&data); |
1075 DVLOG(2) << "Gaia fetcher response code: " << response_code; | 1086 #ifndef NDEBUG |
1076 DVLOG(2) << "Gaia fetcher response data: " << data; | 1087 std::string headers; |
| 1088 if (source->GetResponseHeaders()) |
| 1089 source->GetResponseHeaders()->GetNormalizedHeaders(&headers); |
| 1090 DVLOG(2) << "Response " << url.spec() << ", code = " << response_code << "\n" |
| 1091 << headers << "\n"; |
| 1092 DVLOG(2) << "data: " << data << "\n"; |
| 1093 #endif |
| 1094 // Retrieve the response headers from the request. Must only be called after |
| 1095 // the OnURLFetchComplete callback has run. |
1077 if (url == client_login_gurl_) { | 1096 if (url == client_login_gurl_) { |
1078 OnClientLoginFetched(data, status, response_code); | 1097 OnClientLoginFetched(data, status, response_code); |
1079 } else if (url == issue_auth_token_gurl_) { | 1098 } else if (url == issue_auth_token_gurl_) { |
1080 OnIssueAuthTokenFetched(data, status, response_code); | 1099 OnIssueAuthTokenFetched(data, status, response_code); |
1081 } else if (url == client_login_to_oauth2_gurl_) { | 1100 } else if (url == client_login_to_oauth2_gurl_) { |
1082 OnClientLoginToOAuth2Fetched( | 1101 OnClientLoginToOAuth2Fetched( |
1083 data, source->GetCookies(), status, response_code); | 1102 data, source->GetCookies(), status, response_code); |
1084 } else if (url == oauth2_token_gurl_) { | 1103 } else if (url == oauth2_token_gurl_) { |
1085 OnOAuth2TokenPairFetched(data, status, response_code); | 1104 OnOAuth2TokenPairFetched(data, status, response_code); |
1086 } else if (url == get_user_info_gurl_) { | 1105 } else if (url == get_user_info_gurl_) { |
(...skipping 10 matching lines...) Expand all Loading... |
1097 NOTREACHED(); | 1116 NOTREACHED(); |
1098 } | 1117 } |
1099 } | 1118 } |
1100 | 1119 |
1101 // static | 1120 // static |
1102 bool GaiaAuthFetcher::IsSecondFactorSuccess( | 1121 bool GaiaAuthFetcher::IsSecondFactorSuccess( |
1103 const std::string& alleged_error) { | 1122 const std::string& alleged_error) { |
1104 return alleged_error.find(kSecondFactor) != | 1123 return alleged_error.find(kSecondFactor) != |
1105 std::string::npos; | 1124 std::string::npos; |
1106 } | 1125 } |
OLD | NEW |