| 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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 // TODO(chron): These urls are also in auth_response_handler.h. | 87 // TODO(chron): These urls are also in auth_response_handler.h. |
| 88 // The URLs for different calls in the Google Accounts programmatic login API. | 88 // The URLs for different calls in the Google Accounts programmatic login API. |
| 89 const char GaiaAuthFetcher::kClientLoginUrl[] = | 89 const char GaiaAuthFetcher::kClientLoginUrl[] = |
| 90 "https://www.google.com/accounts/ClientLogin"; | 90 "https://www.google.com/accounts/ClientLogin"; |
| 91 const char GaiaAuthFetcher::kIssueAuthTokenUrl[] = | 91 const char GaiaAuthFetcher::kIssueAuthTokenUrl[] = |
| 92 "https://www.google.com/accounts/IssueAuthToken"; | 92 "https://www.google.com/accounts/IssueAuthToken"; |
| 93 const char GaiaAuthFetcher::kGetUserInfoUrl[] = | 93 const char GaiaAuthFetcher::kGetUserInfoUrl[] = |
| 94 "https://www.google.com/accounts/GetUserInfo"; | 94 "https://www.google.com/accounts/GetUserInfo"; |
| 95 | 95 |
| 96 GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer, | 96 GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer, |
| 97 const std::string& source, | 97 const std::string& source, |
| 98 net::URLRequestContextGetter* getter) | 98 net::URLRequestContextGetter* getter) |
| 99 : consumer_(consumer), | 99 : AuthenticationFetcher(consumer, source, getter), |
| 100 getter_(getter), | |
| 101 source_(source), | |
| 102 client_login_gurl_(kClientLoginUrl), | 100 client_login_gurl_(kClientLoginUrl), |
| 103 issue_auth_token_gurl_(kIssueAuthTokenUrl), | 101 issue_auth_token_gurl_(kIssueAuthTokenUrl), |
| 104 get_user_info_gurl_(kGetUserInfoUrl), | 102 get_user_info_gurl_(kGetUserInfoUrl) {} |
| 105 fetch_pending_(false) {} | |
| 106 | 103 |
| 107 GaiaAuthFetcher::~GaiaAuthFetcher() {} | 104 GaiaAuthFetcher::~GaiaAuthFetcher() {} |
| 108 | 105 |
| 109 bool GaiaAuthFetcher::HasPendingFetch() { | |
| 110 return fetch_pending_; | |
| 111 } | |
| 112 | |
| 113 void GaiaAuthFetcher::CancelRequest() { | |
| 114 fetcher_.reset(); | |
| 115 fetch_pending_ = false; | |
| 116 } | |
| 117 | |
| 118 // static | 106 // static |
| 119 URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( | 107 URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( |
| 120 net::URLRequestContextGetter* getter, | 108 net::URLRequestContextGetter* getter, |
| 121 const std::string& body, | 109 const std::string& body, |
| 122 const GURL& gaia_gurl, | 110 const GURL& gaia_gurl, |
| 123 URLFetcher::Delegate* delegate) { | 111 URLFetcher::Delegate* delegate) { |
| 124 | 112 |
| 125 URLFetcher* to_return = | 113 URLFetcher* to_return = |
| 126 URLFetcher::Create(0, | 114 URLFetcher::Create(0, |
| 127 gaia_gurl, | 115 gaia_gurl, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 account_type, | 156 account_type, |
| 169 source.c_str(), | 157 source.c_str(), |
| 170 service, | 158 service, |
| 171 encoded_login_token.c_str(), | 159 encoded_login_token.c_str(), |
| 172 encoded_login_captcha.c_str()); | 160 encoded_login_captcha.c_str()); |
| 173 | 161 |
| 174 } | 162 } |
| 175 | 163 |
| 176 // static | 164 // static |
| 177 std::string GaiaAuthFetcher::MakeIssueAuthTokenBody( | 165 std::string GaiaAuthFetcher::MakeIssueAuthTokenBody( |
| 178 const std::string& sid, | 166 const AuthenticationConsumer::AuthenticationResult& credentials, |
| 179 const std::string& lsid, | |
| 180 const char* const service) { | 167 const char* const service) { |
| 181 std::string encoded_sid = UrlEncodeString(sid); | 168 const GaiaAuthConsumer::ClientLoginResult& cred = |
| 182 std::string encoded_lsid = UrlEncodeString(lsid); | 169 static_cast<const GaiaAuthConsumer::ClientLoginResult&>(credentials); |
| 170 std::string encoded_sid = UrlEncodeString(cred.sid); |
| 171 std::string encoded_lsid = UrlEncodeString(cred.lsid); |
| 183 | 172 |
| 184 // All tokens should be session tokens except the gaia auth token. | 173 // All tokens should be session tokens except the gaia auth token. |
| 185 bool session = true; | 174 bool session = true; |
| 186 if (!strcmp(service, GaiaConstants::kGaiaService)) | 175 if (!strcmp(service, GaiaConstants::kGaiaService)) |
| 187 session = false; | 176 session = false; |
| 188 | 177 |
| 189 return base::StringPrintf(kIssueAuthTokenFormat, | 178 return base::StringPrintf(kIssueAuthTokenFormat, |
| 190 encoded_sid.c_str(), | 179 encoded_sid.c_str(), |
| 191 encoded_lsid.c_str(), | 180 encoded_lsid.c_str(), |
| 192 service, | 181 service, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 } else if (i->first == kErrorUrlParam) { | 231 } else if (i->first == kErrorUrlParam) { |
| 243 error_url->assign(i->second); | 232 error_url->assign(i->second); |
| 244 } else if (i->first == kCaptchaUrlParam) { | 233 } else if (i->first == kCaptchaUrlParam) { |
| 245 captcha_url->assign(i->second); | 234 captcha_url->assign(i->second); |
| 246 } else if (i->first == kCaptchaTokenParam) { | 235 } else if (i->first == kCaptchaTokenParam) { |
| 247 captcha_token->assign(i->second); | 236 captcha_token->assign(i->second); |
| 248 } | 237 } |
| 249 } | 238 } |
| 250 } | 239 } |
| 251 | 240 |
| 241 // virtual |
| 242 void GaiaAuthFetcher::StartAuthentication( |
| 243 const std::string& username, |
| 244 const std::string& password, |
| 245 const char* const service, |
| 246 const std::string& login_token, |
| 247 const std::string& login_captcha, |
| 248 HostedAccountsSetting allow_hosted_accounts) { |
| 249 StartClientLogin(username, password, service, login_token, login_captcha, |
| 250 allow_hosted_accounts); |
| 251 } |
| 252 |
| 252 void GaiaAuthFetcher::StartClientLogin( | 253 void GaiaAuthFetcher::StartClientLogin( |
| 253 const std::string& username, | 254 const std::string& username, |
| 254 const std::string& password, | 255 const std::string& password, |
| 255 const char* const service, | 256 const char* const service, |
| 256 const std::string& login_token, | 257 const std::string& login_token, |
| 257 const std::string& login_captcha, | 258 const std::string& login_captcha, |
| 258 HostedAccountsSetting allow_hosted_accounts) { | 259 HostedAccountsSetting allow_hosted_accounts) { |
| 259 | 260 |
| 260 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 261 DCHECK(!HasPendingFetch()) << "Tried to fetch two things at once!"; |
| 261 | 262 |
| 262 // This class is thread agnostic, so be sure to call this only on the | 263 // This class is thread agnostic, so be sure to call this only on the |
| 263 // same thread each time. | 264 // same thread each time. |
| 264 VLOG(1) << "Starting new ClientLogin fetch for:" << username; | 265 VLOG(1) << "Starting new ClientLogin fetch for:" << username; |
| 265 | 266 |
| 266 // Must outlive fetcher_. | 267 // Must outlive fetcher_. |
| 267 request_body_ = MakeClientLoginBody(username, | 268 request_body_ = MakeClientLoginBody(username, |
| 268 password, | 269 password, |
| 269 source_, | 270 source_, |
| 270 service, | 271 service, |
| 271 login_token, | 272 login_token, |
| 272 login_captcha, | 273 login_captcha, |
| 273 allow_hosted_accounts); | 274 allow_hosted_accounts); |
| 274 fetcher_.reset(CreateGaiaFetcher(getter_, | 275 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 275 request_body_, | 276 request_body_, |
| 276 client_login_gurl_, | 277 client_login_gurl_, |
| 277 this)); | 278 this)); |
| 278 fetch_pending_ = true; | 279 SetPending(); |
| 279 fetcher_->Start(); | 280 fetcher_->Start(); |
| 280 } | 281 } |
| 281 | 282 |
| 282 void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid, | 283 void GaiaAuthFetcher::StartIssueAuthToken( |
| 283 const std::string& lsid, | 284 const AuthenticationConsumer::AuthenticationResult& credentials, |
| 284 const char* const service) { | 285 const char* const service) { |
| 285 | 286 |
| 286 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 287 DCHECK(!HasPendingFetch()) << "Tried to fetch two things at once!"; |
| 287 | 288 |
| 288 VLOG(1) << "Starting IssueAuthToken for: " << service; | 289 VLOG(1) << "Starting IssueAuthToken for: " << service; |
| 289 requested_service_ = service; | 290 requested_service_ = service; |
| 290 request_body_ = MakeIssueAuthTokenBody(sid, lsid, service); | 291 request_body_ = MakeIssueAuthTokenBody(credentials, service); |
| 291 fetcher_.reset(CreateGaiaFetcher(getter_, | 292 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 292 request_body_, | 293 request_body_, |
| 293 issue_auth_token_gurl_, | 294 issue_auth_token_gurl_, |
| 294 this)); | 295 this)); |
| 295 fetch_pending_ = true; | 296 SetPending(); |
| 296 fetcher_->Start(); | 297 fetcher_->Start(); |
| 297 } | 298 } |
| 298 | 299 |
| 299 void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, | 300 void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, |
| 300 const std::string& info_key) { | 301 const std::string& info_key) { |
| 301 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 302 DCHECK(!HasPendingFetch()) << "Tried to fetch two things at once!"; |
| 302 | 303 |
| 303 VLOG(1) << "Starting GetUserInfo for lsid=" << lsid; | 304 VLOG(1) << "Starting GetUserInfo for lsid=" << lsid; |
| 304 request_body_ = MakeGetUserInfoBody(lsid); | 305 request_body_ = MakeGetUserInfoBody(lsid); |
| 305 fetcher_.reset(CreateGaiaFetcher(getter_, | 306 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 306 request_body_, | 307 request_body_, |
| 307 get_user_info_gurl_, | 308 get_user_info_gurl_, |
| 308 this)); | 309 this)); |
| 309 fetch_pending_ = true; | 310 SetPending(); |
| 310 requested_info_key_ = info_key; | 311 requested_info_key_ = info_key; |
| 311 fetcher_->Start(); | 312 fetcher_->Start(); |
| 312 } | 313 } |
| 313 | 314 |
| 314 // static | 315 // static |
| 315 GoogleServiceAuthError GaiaAuthFetcher::GenerateAuthError( | 316 GoogleServiceAuthError GaiaAuthFetcher::GenerateAuthError( |
| 316 const std::string& data, | 317 const std::string& data, |
| 317 const net::URLRequestStatus& status) { | 318 const net::URLRequestStatus& status) { |
| 318 | 319 |
| 319 if (!status.is_success()) { | 320 if (!status.is_success()) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 | 358 |
| 358 LOG(WARNING) << "Incomprehensible response from Google Accounts servers."; | 359 LOG(WARNING) << "Incomprehensible response from Google Accounts servers."; |
| 359 return GoogleServiceAuthError( | 360 return GoogleServiceAuthError( |
| 360 GoogleServiceAuthError::SERVICE_UNAVAILABLE); | 361 GoogleServiceAuthError::SERVICE_UNAVAILABLE); |
| 361 } | 362 } |
| 362 | 363 |
| 363 NOTREACHED(); | 364 NOTREACHED(); |
| 364 return GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE); | 365 return GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE); |
| 365 } | 366 } |
| 366 | 367 |
| 368 void GaiaAuthFetcher::OnAuthenticationFetched( |
| 369 const std::string& data, |
| 370 const net::URLRequestStatus& status, |
| 371 int response_code) { |
| 372 OnClientLoginFetched(data, status, response_code); |
| 373 } |
| 374 |
| 367 void GaiaAuthFetcher::OnClientLoginFetched(const std::string& data, | 375 void GaiaAuthFetcher::OnClientLoginFetched(const std::string& data, |
| 368 const net::URLRequestStatus& status, | 376 const net::URLRequestStatus& status, |
| 369 int response_code) { | 377 int response_code) { |
| 370 | 378 |
| 371 if (status.is_success() && response_code == RC_REQUEST_OK) { | 379 if (status.is_success() && response_code == RC_REQUEST_OK) { |
| 372 VLOG(1) << "ClientLogin successful!"; | 380 VLOG(1) << "ClientLogin successful!"; |
| 373 std::string sid; | 381 std::string sid; |
| 374 std::string lsid; | 382 std::string lsid; |
| 375 std::string token; | 383 std::string token; |
| 376 ParseClientLoginResponse(data, &sid, &lsid, &token); | 384 ParseClientLoginResponse(data, &sid, &lsid, &token); |
| 377 consumer_->OnClientLoginSuccess( | 385 consumer_->OnAuthenticationSuccess( |
| 378 GaiaAuthConsumer::ClientLoginResult(sid, lsid, token, data)); | 386 GaiaAuthConsumer::ClientLoginResult(sid, lsid, token, data)); |
| 379 } else { | 387 } else { |
| 380 consumer_->OnClientLoginFailure(GenerateAuthError(data, status)); | 388 // consumer_->OnClientLoginFailure(GenerateAuthError(data, status)); |
| 389 consumer_->OnAuthenticationFailure(GenerateAuthError(data, status)); |
| 381 } | 390 } |
| 382 } | 391 } |
| 383 | 392 |
| 384 void GaiaAuthFetcher::OnIssueAuthTokenFetched( | 393 void GaiaAuthFetcher::OnIssueAuthTokenFetched( |
| 385 const std::string& data, | 394 const std::string& data, |
| 386 const net::URLRequestStatus& status, | 395 const net::URLRequestStatus& status, |
| 387 int response_code) { | 396 int response_code) { |
| 388 if (status.is_success() && response_code == RC_REQUEST_OK) { | 397 if (status.is_success() && response_code == RC_REQUEST_OK) { |
| 389 // Only the bare token is returned in the body of this Gaia call | 398 // Only the bare token is returned in the body of this Gaia call |
| 390 // without any padding. | 399 // without any padding. |
| 391 consumer_->OnIssueAuthTokenSuccess(requested_service_, data); | 400 consumer_->OnIssueTokenSuccess(requested_service_, data); |
| 392 } else { | 401 } else { |
| 393 consumer_->OnIssueAuthTokenFailure(requested_service_, | 402 consumer_->OnIssueTokenFailure(requested_service_, |
| 394 GenerateAuthError(data, status)); | 403 GenerateAuthError(data, status)); |
| 395 } | 404 } |
| 396 } | 405 } |
| 397 | 406 |
| 407 // virtual |
| 408 void GaiaAuthFetcher::OnIssueTokenFetched(const std::string& data, |
| 409 const net::URLRequestStatus& status, |
| 410 int response_code) { |
| 411 OnIssueAuthTokenFetched(data, status, response_code); |
| 412 } |
| 413 |
| 398 void GaiaAuthFetcher::OnGetUserInfoFetched( | 414 void GaiaAuthFetcher::OnGetUserInfoFetched( |
| 399 const std::string& data, | 415 const std::string& data, |
| 400 const net::URLRequestStatus& status, | 416 const net::URLRequestStatus& status, |
| 401 int response_code) { | 417 int response_code) { |
| 402 using std::vector; | 418 using std::vector; |
| 403 using std::string; | 419 using std::string; |
| 404 using std::pair; | 420 using std::pair; |
| 405 | 421 |
| 406 if (status.is_success() && response_code == RC_REQUEST_OK) { | 422 if (status.is_success() && response_code == RC_REQUEST_OK) { |
| 407 vector<pair<string, string> > tokens; | 423 vector<pair<string, string> > tokens; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 418 consumer_->OnGetUserInfoFailure(GenerateAuthError(data, status)); | 434 consumer_->OnGetUserInfoFailure(GenerateAuthError(data, status)); |
| 419 } | 435 } |
| 420 } | 436 } |
| 421 | 437 |
| 422 void GaiaAuthFetcher::OnURLFetchComplete(const URLFetcher* source, | 438 void GaiaAuthFetcher::OnURLFetchComplete(const URLFetcher* source, |
| 423 const GURL& url, | 439 const GURL& url, |
| 424 const net::URLRequestStatus& status, | 440 const net::URLRequestStatus& status, |
| 425 int response_code, | 441 int response_code, |
| 426 const ResponseCookies& cookies, | 442 const ResponseCookies& cookies, |
| 427 const std::string& data) { | 443 const std::string& data) { |
| 428 fetch_pending_ = false; | 444 ClearPending(); |
| 429 if (url == client_login_gurl_) { | 445 if (url == client_login_gurl_) { |
| 430 OnClientLoginFetched(data, status, response_code); | 446 OnClientLoginFetched(data, status, response_code); |
| 431 } else if (url == issue_auth_token_gurl_) { | 447 } else if (url == issue_auth_token_gurl_) { |
| 432 OnIssueAuthTokenFetched(data, status, response_code); | 448 OnIssueAuthTokenFetched(data, status, response_code); |
| 433 } else if (url == get_user_info_gurl_) { | 449 } else if (url == get_user_info_gurl_) { |
| 434 OnGetUserInfoFetched(data, status, response_code); | 450 OnGetUserInfoFetched(data, status, response_code); |
| 435 } else { | 451 } else { |
| 436 NOTREACHED(); | 452 NOTREACHED(); |
| 437 } | 453 } |
| 438 } | 454 } |
| 439 | 455 |
| 440 // static | 456 // static |
| 441 bool GaiaAuthFetcher::IsSecondFactorSuccess( | 457 bool GaiaAuthFetcher::IsSecondFactorSuccess( |
| 442 const std::string& alleged_error) { | 458 const std::string& alleged_error) { |
| 443 return alleged_error.find(kSecondFactor) != | 459 return alleged_error.find(kSecondFactor) != |
| 444 std::string::npos; | 460 std::string::npos; |
| 445 } | 461 } |
| OLD | NEW |