| 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::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 |
| 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::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 |
| 103 GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer, | 144 GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer, |
| 104 const std::string& source, | 145 const std::string& source, |
| 105 net::URLRequestContextGetter* getter) | 146 net::URLRequestContextGetter* getter) |
| 106 : consumer_(consumer), | 147 : consumer_(consumer), |
| 107 getter_(getter), | 148 getter_(getter), |
| 108 source_(source), | 149 source_(source), |
| 109 client_login_gurl_(GaiaUrls::GetInstance()->client_login_url()), | 150 client_login_gurl_(GaiaUrls::GetInstance()->client_login_url()), |
| 110 issue_auth_token_gurl_(GaiaUrls::GetInstance()->issue_auth_token_url()), | 151 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()), |
| 111 get_user_info_gurl_(GaiaUrls::GetInstance()->get_user_info_url()), | 155 get_user_info_gurl_(GaiaUrls::GetInstance()->get_user_info_url()), |
| 112 token_auth_gurl_(GaiaUrls::GetInstance()->token_auth_url()), | 156 token_auth_gurl_(GaiaUrls::GetInstance()->token_auth_url()), |
| 113 merge_session_gurl_(GaiaUrls::GetInstance()->merge_session_url()), | 157 merge_session_gurl_(GaiaUrls::GetInstance()->merge_session_url()), |
| 114 fetch_pending_(false) {} | 158 fetch_pending_(false) {} |
| 115 | 159 |
| 116 GaiaAuthFetcher::~GaiaAuthFetcher() {} | 160 GaiaAuthFetcher::~GaiaAuthFetcher() {} |
| 117 | 161 |
| 118 bool GaiaAuthFetcher::HasPendingFetch() { | 162 bool GaiaAuthFetcher::HasPendingFetch() { |
| 119 return fetch_pending_; | 163 return fetch_pending_; |
| 120 } | 164 } |
| 121 | 165 |
| 122 void GaiaAuthFetcher::CancelRequest() { | 166 void GaiaAuthFetcher::CancelRequest() { |
| 123 fetcher_.reset(); | 167 fetcher_.reset(); |
| 124 fetch_pending_ = false; | 168 fetch_pending_ = false; |
| 125 } | 169 } |
| 126 | 170 |
| 127 // static | 171 // static |
| 128 content::URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( | 172 content::URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( |
| 129 net::URLRequestContextGetter* getter, | 173 net::URLRequestContextGetter* getter, |
| 130 const std::string& body, | 174 const std::string& body, |
| 175 const std::string& headers, |
| 131 const GURL& gaia_gurl, | 176 const GURL& gaia_gurl, |
| 132 bool send_cookies, | 177 bool use_cookies, |
| 133 content::URLFetcherDelegate* delegate) { | 178 content::URLFetcherDelegate* delegate) { |
| 134 content::URLFetcher* to_return = content::URLFetcher::Create( | 179 content::URLFetcher* to_return = content::URLFetcher::Create( |
| 135 0, gaia_gurl, content::URLFetcher::POST, delegate); | 180 0, gaia_gurl, content::URLFetcher::POST, delegate); |
| 136 to_return->SetRequestContext(getter); | 181 to_return->SetRequestContext(getter); |
| 137 to_return->SetUploadData("application/x-www-form-urlencoded", body); | 182 to_return->SetUploadData("application/x-www-form-urlencoded", body); |
| 138 | 183 |
| 139 // The Gaia token exchange requests do not require any cookie-based | 184 // The Gaia token exchange requests do not require any cookie-based |
| 140 // identification as part of requests. We suppress sending any cookies to | 185 // identification as part of requests. We suppress sending any cookies to |
| 141 // maintain a separation between the user's browsing and Chrome's internal | 186 // maintain a separation between the user's browsing and Chrome's internal |
| 142 // services. Where such mixing is desired (MergeSession), it will be done | 187 // services. Where such mixing is desired (MergeSession), it will be done |
| 143 // explicitly. | 188 // explicitly. |
| 144 if (!send_cookies) | 189 if (!use_cookies) { |
| 145 to_return->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES); | 190 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); |
| 146 | 195 |
| 147 return to_return; | 196 return to_return; |
| 148 } | 197 } |
| 149 | 198 |
| 150 // static | 199 // static |
| 151 std::string GaiaAuthFetcher::MakeClientLoginBody( | 200 std::string GaiaAuthFetcher::MakeClientLoginBody( |
| 152 const std::string& username, | 201 const std::string& username, |
| 153 const std::string& password, | 202 const std::string& password, |
| 154 const std::string& source, | 203 const std::string& source, |
| 155 const char* service, | 204 const char* service, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 session = false; | 251 session = false; |
| 203 | 252 |
| 204 return base::StringPrintf(kIssueAuthTokenFormat, | 253 return base::StringPrintf(kIssueAuthTokenFormat, |
| 205 encoded_sid.c_str(), | 254 encoded_sid.c_str(), |
| 206 encoded_lsid.c_str(), | 255 encoded_lsid.c_str(), |
| 207 service, | 256 service, |
| 208 session ? "true" : "false"); | 257 session ? "true" : "false"); |
| 209 } | 258 } |
| 210 | 259 |
| 211 // static | 260 // 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 |
| 212 std::string GaiaAuthFetcher::MakeGetUserInfoBody(const std::string& lsid) { | 289 std::string GaiaAuthFetcher::MakeGetUserInfoBody(const std::string& lsid) { |
| 213 std::string encoded_lsid = net::EscapeUrlEncodedData(lsid, true); | 290 std::string encoded_lsid = net::EscapeUrlEncodedData(lsid, true); |
| 214 return base::StringPrintf(kGetUserInfoFormat, encoded_lsid.c_str()); | 291 return base::StringPrintf(kGetUserInfoFormat, encoded_lsid.c_str()); |
| 215 } | 292 } |
| 216 | 293 |
| 217 // static | 294 // static |
| 218 std::string GaiaAuthFetcher::MakeTokenAuthBody(const std::string& auth_token, | 295 std::string GaiaAuthFetcher::MakeTokenAuthBody(const std::string& auth_token, |
| 219 const std::string& continue_url, | 296 const std::string& continue_url, |
| 220 const std::string& source) { | 297 const std::string& source) { |
| 221 std::string encoded_auth_token = net::EscapeUrlEncodedData(auth_token, true); | 298 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); | 313 std::string encoded_auth_token = net::EscapeUrlEncodedData(auth_token, true); |
| 237 std::string encoded_continue_url = net::EscapeUrlEncodedData(continue_url, | 314 std::string encoded_continue_url = net::EscapeUrlEncodedData(continue_url, |
| 238 true); | 315 true); |
| 239 std::string encoded_source = net::EscapeUrlEncodedData(source, true); | 316 std::string encoded_source = net::EscapeUrlEncodedData(source, true); |
| 240 return base::StringPrintf(kMergeSessionFormat, | 317 return base::StringPrintf(kMergeSessionFormat, |
| 241 encoded_auth_token.c_str(), | 318 encoded_auth_token.c_str(), |
| 242 encoded_continue_url.c_str(), | 319 encoded_continue_url.c_str(), |
| 243 encoded_source.c_str()); | 320 encoded_source.c_str()); |
| 244 } | 321 } |
| 245 | 322 |
| 323 // static |
| 324 std::string GaiaAuthFetcher::MakeGetAuthCodeHeader( |
| 325 const std::string& auth_token) { |
| 326 return StringPrintf(kAuthHeaderFormat, auth_token.c_str()); |
| 327 } |
| 328 |
| 246 // Helper method that extracts tokens from a successful reply. | 329 // Helper method that extracts tokens from a successful reply. |
| 247 // static | 330 // static |
| 248 void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data, | 331 void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data, |
| 249 std::string* sid, | 332 std::string* sid, |
| 250 std::string* lsid, | 333 std::string* lsid, |
| 251 std::string* token) { | 334 std::string* token) { |
| 252 using std::vector; | 335 using std::vector; |
| 253 using std::pair; | 336 using std::pair; |
| 254 using std::string; | 337 using std::string; |
| 255 | 338 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 286 } else if (i->first == kErrorUrlParam) { | 369 } else if (i->first == kErrorUrlParam) { |
| 287 error_url->assign(i->second); | 370 error_url->assign(i->second); |
| 288 } else if (i->first == kCaptchaUrlParam) { | 371 } else if (i->first == kCaptchaUrlParam) { |
| 289 captcha_url->assign(i->second); | 372 captcha_url->assign(i->second); |
| 290 } else if (i->first == kCaptchaTokenParam) { | 373 } else if (i->first == kCaptchaTokenParam) { |
| 291 captcha_token->assign(i->second); | 374 captcha_token->assign(i->second); |
| 292 } | 375 } |
| 293 } | 376 } |
| 294 } | 377 } |
| 295 | 378 |
| 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 |
| 296 void GaiaAuthFetcher::StartClientLogin( | 445 void GaiaAuthFetcher::StartClientLogin( |
| 297 const std::string& username, | 446 const std::string& username, |
| 298 const std::string& password, | 447 const std::string& password, |
| 299 const char* const service, | 448 const char* const service, |
| 300 const std::string& login_token, | 449 const std::string& login_token, |
| 301 const std::string& login_captcha, | 450 const std::string& login_captcha, |
| 302 HostedAccountsSetting allow_hosted_accounts) { | 451 HostedAccountsSetting allow_hosted_accounts) { |
| 303 | 452 |
| 304 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 453 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
| 305 | 454 |
| 306 // This class is thread agnostic, so be sure to call this only on the | 455 // This class is thread agnostic, so be sure to call this only on the |
| 307 // same thread each time. | 456 // same thread each time. |
| 308 DVLOG(1) << "Starting new ClientLogin fetch for:" << username; | 457 DVLOG(1) << "Starting new ClientLogin fetch for:" << username; |
| 309 | 458 |
| 310 // Must outlive fetcher_. | 459 // Must outlive fetcher_. |
| 311 request_body_ = MakeClientLoginBody(username, | 460 request_body_ = MakeClientLoginBody(username, |
| 312 password, | 461 password, |
| 313 source_, | 462 source_, |
| 314 service, | 463 service, |
| 315 login_token, | 464 login_token, |
| 316 login_captcha, | 465 login_captcha, |
| 317 allow_hosted_accounts); | 466 allow_hosted_accounts); |
| 318 fetcher_.reset(CreateGaiaFetcher(getter_, | 467 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 319 request_body_, | 468 request_body_, |
| 469 "", |
| 320 client_login_gurl_, | 470 client_login_gurl_, |
| 321 false, | 471 false, |
| 322 this)); | 472 this)); |
| 323 fetch_pending_ = true; | 473 fetch_pending_ = true; |
| 324 fetcher_->Start(); | 474 fetcher_->Start(); |
| 325 } | 475 } |
| 326 | 476 |
| 327 void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid, | 477 void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid, |
| 328 const std::string& lsid, | 478 const std::string& lsid, |
| 329 const char* const service) { | 479 const char* const service) { |
| 330 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 480 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
| 331 | 481 |
| 332 DVLOG(1) << "Starting IssueAuthToken for: " << service; | 482 DVLOG(1) << "Starting IssueAuthToken for: " << service; |
| 333 requested_service_ = service; | 483 requested_service_ = service; |
| 334 request_body_ = MakeIssueAuthTokenBody(sid, lsid, service); | 484 request_body_ = MakeIssueAuthTokenBody(sid, lsid, service); |
| 335 fetcher_.reset(CreateGaiaFetcher(getter_, | 485 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 336 request_body_, | 486 request_body_, |
| 487 "", |
| 337 issue_auth_token_gurl_, | 488 issue_auth_token_gurl_, |
| 338 false, | 489 false, |
| 339 this)); | 490 this)); |
| 340 fetch_pending_ = true; | 491 fetch_pending_ = true; |
| 341 fetcher_->Start(); | 492 fetcher_->Start(); |
| 342 } | 493 } |
| 343 | 494 |
| 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 |
| 344 void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, | 511 void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, |
| 345 const std::string& info_key) { | 512 const std::string& info_key) { |
| 346 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 513 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
| 347 | 514 |
| 348 DVLOG(1) << "Starting GetUserInfo for lsid=" << lsid; | 515 DVLOG(1) << "Starting GetUserInfo for lsid=" << lsid; |
| 349 request_body_ = MakeGetUserInfoBody(lsid); | 516 request_body_ = MakeGetUserInfoBody(lsid); |
| 350 fetcher_.reset(CreateGaiaFetcher(getter_, | 517 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 351 request_body_, | 518 request_body_, |
| 519 "", |
| 352 get_user_info_gurl_, | 520 get_user_info_gurl_, |
| 353 false, | 521 false, |
| 354 this)); | 522 this)); |
| 355 fetch_pending_ = true; | 523 fetch_pending_ = true; |
| 356 requested_info_key_ = info_key; | 524 requested_info_key_ = info_key; |
| 357 fetcher_->Start(); | 525 fetcher_->Start(); |
| 358 } | 526 } |
| 359 | 527 |
| 360 void GaiaAuthFetcher::StartTokenAuth(const std::string& auth_token) { | 528 void GaiaAuthFetcher::StartTokenAuth(const std::string& auth_token) { |
| 361 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 529 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
| 362 | 530 |
| 363 DVLOG(1) << "Starting TokenAuth with auth_token=" << auth_token; | 531 DVLOG(1) << "Starting TokenAuth with auth_token=" << auth_token; |
| 364 | 532 |
| 365 // The continue URL is a required parameter of the TokenAuth API, but in this | 533 // 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 | 534 // case we don't actually need or want to navigate to it. Setting it to |
| 367 // an arbitrary Google URL. | 535 // an arbitrary Google URL. |
| 368 std::string continue_url("http://www.google.com"); | 536 std::string continue_url("http://www.google.com"); |
| 369 request_body_ = MakeTokenAuthBody(auth_token, continue_url, source_); | 537 request_body_ = MakeTokenAuthBody(auth_token, continue_url, source_); |
| 370 fetcher_.reset(CreateGaiaFetcher(getter_, | 538 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 371 request_body_, | 539 request_body_, |
| 540 "", |
| 372 token_auth_gurl_, | 541 token_auth_gurl_, |
| 373 false, | 542 false, |
| 374 this)); | 543 this)); |
| 375 fetch_pending_ = true; | 544 fetch_pending_ = true; |
| 376 fetcher_->Start(); | 545 fetcher_->Start(); |
| 377 } | 546 } |
| 378 | 547 |
| 379 void GaiaAuthFetcher::StartMergeSession(const std::string& auth_token) { | 548 void GaiaAuthFetcher::StartMergeSession(const std::string& auth_token) { |
| 380 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 549 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
| 381 | 550 |
| 382 DVLOG(1) << "Starting MergeSession with auth_token=" << auth_token; | 551 DVLOG(1) << "Starting MergeSession with auth_token=" << auth_token; |
| 383 | 552 |
| 384 // The continue URL is a required parameter of the MergeSession API, but in | 553 // 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 | 554 // this case we don't actually need or want to navigate to it. Setting it to |
| 386 // an arbitrary Google URL. | 555 // an arbitrary Google URL. |
| 387 // | 556 // |
| 388 // In order for the new session to be merged correctly, the server needs to | 557 // 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 | 558 // 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 | 559 // created such that it sends the cookies with the request, which is |
| 391 // different from all other requests the fetcher can make. | 560 // different from all other requests the fetcher can make. |
| 392 std::string continue_url("http://www.google.com"); | 561 std::string continue_url("http://www.google.com"); |
| 393 request_body_ = MakeMergeSessionBody(auth_token, continue_url, source_); | 562 request_body_ = MakeMergeSessionBody(auth_token, continue_url, source_); |
| 394 fetcher_.reset(CreateGaiaFetcher(getter_, | 563 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 395 request_body_, | 564 request_body_, |
| 565 "", |
| 396 merge_session_gurl_, | 566 merge_session_gurl_, |
| 397 true, | 567 true, |
| 398 this)); | 568 this)); |
| 399 fetch_pending_ = true; | 569 fetch_pending_ = true; |
| 400 fetcher_->Start(); | 570 fetcher_->Start(); |
| 401 } | 571 } |
| 402 | 572 |
| 403 // static | 573 // static |
| 404 GoogleServiceAuthError GaiaAuthFetcher::GenerateAuthError( | 574 GoogleServiceAuthError GaiaAuthFetcher::GenerateAuthError( |
| 405 const std::string& data, | 575 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) { | 699 if (status.is_success() && response_code == RC_REQUEST_OK) { |
| 530 // Only the bare token is returned in the body of this Gaia call | 700 // Only the bare token is returned in the body of this Gaia call |
| 531 // without any padding. | 701 // without any padding. |
| 532 consumer_->OnIssueAuthTokenSuccess(requested_service_, data); | 702 consumer_->OnIssueAuthTokenSuccess(requested_service_, data); |
| 533 } else { | 703 } else { |
| 534 consumer_->OnIssueAuthTokenFailure(requested_service_, | 704 consumer_->OnIssueAuthTokenFailure(requested_service_, |
| 535 GenerateAuthError(data, status)); | 705 GenerateAuthError(data, status)); |
| 536 } | 706 } |
| 537 } | 707 } |
| 538 | 708 |
| 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 ParseClientLoginToOAuth2Response(cookies, &auth_code); |
| 717 StartOAuth2TokenPairFetch(auth_code); |
| 718 } else { |
| 719 consumer_->OnOAuthLoginTokenFailure(GenerateAuthError(data, status)); |
| 720 } |
| 721 } |
| 722 |
| 723 void GaiaAuthFetcher::StartOAuth2TokenPairFetch(const std::string& auth_code) { |
| 724 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
| 725 |
| 726 DVLOG(1) << "Starting OAuth token pair fetch"; |
| 727 request_body_ = MakeGetTokenPairBody(auth_code); |
| 728 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 729 request_body_, |
| 730 "", |
| 731 oauth2_token_gurl_, |
| 732 false, |
| 733 this)); |
| 734 fetch_pending_ = true; |
| 735 fetcher_->Start(); |
| 736 } |
| 737 |
| 738 void GaiaAuthFetcher::OnOAuth2TokenPairFetched( |
| 739 const std::string& data, |
| 740 const net::URLRequestStatus& status, |
| 741 int response_code) { |
| 742 if (status.is_success() && response_code == RC_REQUEST_OK) { |
| 743 std::string refresh_token; |
| 744 std::string access_token; |
| 745 int expires_in_secs; |
| 746 ParseOAuth2TokenPairResponse( |
| 747 data, &refresh_token, &access_token, &expires_in_secs); |
| 748 consumer_->OnOAuthLoginTokenSuccess( |
| 749 refresh_token, access_token, expires_in_secs); |
| 750 } else { |
| 751 consumer_->OnOAuthLoginTokenFailure(GenerateAuthError(data, status)); |
| 752 } |
| 753 } |
| 754 |
| 539 void GaiaAuthFetcher::OnGetUserInfoFetched( | 755 void GaiaAuthFetcher::OnGetUserInfoFetched( |
| 540 const std::string& data, | 756 const std::string& data, |
| 541 const net::URLRequestStatus& status, | 757 const net::URLRequestStatus& status, |
| 542 int response_code) { | 758 int response_code) { |
| 543 using std::vector; | 759 using std::vector; |
| 544 using std::string; | 760 using std::string; |
| 545 using std::pair; | 761 using std::pair; |
| 546 | 762 |
| 547 if (status.is_success() && response_code == RC_REQUEST_OK) { | 763 if (status.is_success() && response_code == RC_REQUEST_OK) { |
| 548 vector<pair<string, string> > tokens; | 764 vector<pair<string, string> > tokens; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 fetch_pending_ = false; | 800 fetch_pending_ = false; |
| 585 const GURL& url = source->GetURL(); | 801 const GURL& url = source->GetURL(); |
| 586 const net::URLRequestStatus& status = source->GetStatus(); | 802 const net::URLRequestStatus& status = source->GetStatus(); |
| 587 int response_code = source->GetResponseCode(); | 803 int response_code = source->GetResponseCode(); |
| 588 std::string data; | 804 std::string data; |
| 589 source->GetResponseAsString(&data); | 805 source->GetResponseAsString(&data); |
| 590 if (url == client_login_gurl_) { | 806 if (url == client_login_gurl_) { |
| 591 OnClientLoginFetched(data, status, response_code); | 807 OnClientLoginFetched(data, status, response_code); |
| 592 } else if (url == issue_auth_token_gurl_) { | 808 } else if (url == issue_auth_token_gurl_) { |
| 593 OnIssueAuthTokenFetched(data, status, response_code); | 809 OnIssueAuthTokenFetched(data, status, response_code); |
| 810 } else if (url == client_login_to_oauth2_gurl_) { |
| 811 OnClientLoginToOAuth2Fetched( |
| 812 data, source->GetCookies(), status, response_code); |
| 813 } else if (url == oauth2_token_gurl_) { |
| 814 OnOAuth2TokenPairFetched(data, status, response_code); |
| 594 } else if (url == get_user_info_gurl_) { | 815 } else if (url == get_user_info_gurl_) { |
| 595 OnGetUserInfoFetched(data, status, response_code); | 816 OnGetUserInfoFetched(data, status, response_code); |
| 596 } else if (url == token_auth_gurl_) { | 817 } else if (url == token_auth_gurl_) { |
| 597 OnTokenAuthFetched(data, status, response_code); | 818 OnTokenAuthFetched(data, status, response_code); |
| 598 } else if (url == merge_session_gurl_ || | 819 } else if (url == merge_session_gurl_ || |
| 599 (source && source->GetOriginalURL() == merge_session_gurl_)) { | 820 (source && source->GetOriginalURL() == merge_session_gurl_)) { |
| 600 // MergeSession may redirect, so check the original URL of the fetcher. | 821 // MergeSession may redirect, so check the original URL of the fetcher. |
| 601 OnMergeSessionFetched(data, status, response_code); | 822 OnMergeSessionFetched(data, status, response_code); |
| 602 } else { | 823 } else { |
| 603 NOTREACHED(); | 824 NOTREACHED(); |
| 604 } | 825 } |
| 605 } | 826 } |
| 606 | 827 |
| 607 // static | 828 // static |
| 608 bool GaiaAuthFetcher::IsSecondFactorSuccess( | 829 bool GaiaAuthFetcher::IsSecondFactorSuccess( |
| 609 const std::string& alleged_error) { | 830 const std::string& alleged_error) { |
| 610 return alleged_error.find(kSecondFactor) != | 831 return alleged_error.find(kSecondFactor) != |
| 611 std::string::npos; | 832 std::string::npos; |
| 612 } | 833 } |
| OLD | NEW |