| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/autofill/wallet/wallet_client.h" | |
| 6 | |
| 7 #include "base/json/json_reader.h" | |
| 8 #include "base/json/json_writer.h" | |
| 9 #include "base/logging.h" | |
| 10 #include "base/memory/scoped_ptr.h" | |
| 11 #include "base/string_util.h" | |
| 12 #include "chrome/browser/autofill/wallet/cart.h" | |
| 13 #include "chrome/browser/autofill/wallet/instrument.h" | |
| 14 #include "chrome/browser/autofill/wallet/wallet_address.h" | |
| 15 #include "chrome/browser/autofill/wallet/wallet_client_observer.h" | |
| 16 #include "chrome/browser/autofill/wallet/wallet_items.h" | |
| 17 #include "chrome/browser/autofill/wallet/wallet_service_url.h" | |
| 18 #include "crypto/random.h" | |
| 19 #include "google_apis/google_api_keys.h" | |
| 20 #include "googleurl/src/gurl.h" | |
| 21 #include "net/http/http_status_code.h" | |
| 22 #include "net/url_request/url_fetcher.h" | |
| 23 #include "net/url_request/url_request_context_getter.h" | |
| 24 | |
| 25 namespace autofill { | |
| 26 namespace wallet { | |
| 27 | |
| 28 namespace { | |
| 29 | |
| 30 const char kJsonMimeType[] = "application/json"; | |
| 31 const size_t kOneTimePadLength = 6; | |
| 32 | |
| 33 std::string AutocheckoutStatusToString(AutocheckoutStatus status) { | |
| 34 switch (status) { | |
| 35 case MISSING_FIELDMAPPING: | |
| 36 return "MISSING_FIELDMAPPING"; | |
| 37 case MISSING_ADVANCE: | |
| 38 return "MISSING_ADVANCE"; | |
| 39 case CANNOT_PROCEED: | |
| 40 return "CANNOT_PROCEED"; | |
| 41 case SUCCESS: | |
| 42 // SUCCESS cannot be sent to the server as it will result in a failure. | |
| 43 NOTREACHED(); | |
| 44 return "ERROR"; | |
| 45 } | |
| 46 NOTREACHED(); | |
| 47 return "NOT_POSSIBLE"; | |
| 48 } | |
| 49 | |
| 50 // Gets and parses required actions from a SaveToWallet response. Returns | |
| 51 // false if any unknown required actions are seen and true otherwise. | |
| 52 void GetRequiredActionsForSaveToWallet( | |
| 53 const base::DictionaryValue& dict, | |
| 54 std::vector<RequiredAction>* required_actions) { | |
| 55 const ListValue* required_action_list; | |
| 56 if (!dict.GetList("required_action", &required_action_list)) | |
| 57 return; | |
| 58 | |
| 59 for (size_t i = 0; i < required_action_list->GetSize(); ++i) { | |
| 60 std::string action_string; | |
| 61 if (required_action_list->GetString(i, &action_string)) { | |
| 62 RequiredAction action = ParseRequiredActionFromString(action_string); | |
| 63 if (!ActionAppliesToSaveToWallet(action)) { | |
| 64 DLOG(ERROR) << "Response from Google wallet with bad required action:" | |
| 65 " \"" << action_string << "\""; | |
| 66 required_actions->clear(); | |
| 67 return; | |
| 68 } | |
| 69 required_actions->push_back(action); | |
| 70 } | |
| 71 } | |
| 72 } | |
| 73 | |
| 74 // Keys for JSON communication with the Online Wallet server. | |
| 75 const char kAcceptedLegalDocumentKey[] = "accepted_legal_document"; | |
| 76 const char kApiKeyKey[] = "api_key"; | |
| 77 const char kAuthResultKey[] = "auth_result"; | |
| 78 const char kCartKey[] = "cart"; | |
| 79 const char kEncryptedOtpKey[] = "encrypted_otp"; | |
| 80 const char kGoogleTransactionIdKey[] = "google_transaction_id"; | |
| 81 const char kInstrumentIdKey[] = "instrument_id"; | |
| 82 const char kInstrumentKey[] = "instrument"; | |
| 83 const char kInstrumentEscrowHandleKey[] = "instrument_escrow_handle"; | |
| 84 const char kInstrumentPhoneNumberKey[] = "instrument_phone_number"; | |
| 85 const char kMerchantDomainKey[] = "merchant_domain"; | |
| 86 const char kReasonKey[] = "reason"; | |
| 87 const char kRiskParamsKey[] = "risk_params"; | |
| 88 const char kSelectedAddressIdKey[] = "selected_address_id"; | |
| 89 const char kSelectedInstrumentIdKey[] = "selected_instrument_id"; | |
| 90 const char kSessionMaterialKey[] = "session_material"; | |
| 91 const char kShippingAddressIdKey[] = "shipping_address_id"; | |
| 92 const char kShippingAddressKey[] = "shipping_address"; | |
| 93 const char kSuccessKey[] = "success"; | |
| 94 const char kUpgradedBillingAddressKey[] = "upgraded_billing_address"; | |
| 95 const char kUpgradedInstrumentIdKey[] = "upgraded_instrument_id"; | |
| 96 | |
| 97 } // namespace | |
| 98 | |
| 99 | |
| 100 WalletClient::WalletClient(net::URLRequestContextGetter* context_getter) | |
| 101 : context_getter_(context_getter), | |
| 102 request_type_(NO_PENDING_REQUEST), | |
| 103 one_time_pad_(kOneTimePadLength), | |
| 104 encryption_escrow_client_(context_getter), | |
| 105 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { | |
| 106 DCHECK(context_getter); | |
| 107 } | |
| 108 | |
| 109 WalletClient::~WalletClient() {} | |
| 110 | |
| 111 void WalletClient::AcceptLegalDocuments( | |
| 112 const std::vector<std::string>& document_ids, | |
| 113 const std::string& google_transaction_id, | |
| 114 const GURL& source_url, | |
| 115 base::WeakPtr<WalletClientObserver> observer) { | |
| 116 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); | |
| 117 request_type_ = ACCEPT_LEGAL_DOCUMENTS; | |
| 118 | |
| 119 base::DictionaryValue request_dict; | |
| 120 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey()); | |
| 121 request_dict.SetString(kGoogleTransactionIdKey, google_transaction_id); | |
| 122 request_dict.SetString(kMerchantDomainKey, | |
| 123 source_url.GetWithEmptyPath().spec()); | |
| 124 ListValue* docs_list = new ListValue(); | |
| 125 for (std::vector<std::string>::const_iterator it = document_ids.begin(); | |
| 126 it != document_ids.end(); | |
| 127 ++it) { | |
| 128 docs_list->AppendString(*it); | |
| 129 } | |
| 130 request_dict.Set(kAcceptedLegalDocumentKey, docs_list); | |
| 131 | |
| 132 std::string post_body; | |
| 133 base::JSONWriter::Write(&request_dict, &post_body); | |
| 134 | |
| 135 MakeWalletRequest(GetAcceptLegalDocumentsUrl(), post_body, observer); | |
| 136 } | |
| 137 | |
| 138 void WalletClient::AuthenticateInstrument( | |
| 139 const std::string& instrument_id, | |
| 140 const std::string& card_verification_number, | |
| 141 const std::string& obfuscated_gaia_id, | |
| 142 base::WeakPtr<WalletClientObserver> observer) { | |
| 143 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); | |
| 144 DCHECK(observer); | |
| 145 DCHECK(pending_request_body_.empty()); | |
| 146 request_type_ = AUTHENTICATE_INSTRUMENT; | |
| 147 observer_ = observer; | |
| 148 | |
| 149 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); | |
| 150 pending_request_body_.SetString(kRiskParamsKey, GetRiskParams()); | |
| 151 pending_request_body_.SetString(kInstrumentIdKey, instrument_id); | |
| 152 | |
| 153 encryption_escrow_client_.EscrowCardVerificationNumber( | |
| 154 card_verification_number, | |
| 155 obfuscated_gaia_id, | |
| 156 weak_ptr_factory_.GetWeakPtr()); | |
| 157 } | |
| 158 | |
| 159 void WalletClient::GetFullWallet(const std::string& instrument_id, | |
| 160 const std::string& address_id, | |
| 161 const GURL& source_url, | |
| 162 const Cart& cart, | |
| 163 const std::string& google_transaction_id, | |
| 164 base::WeakPtr<WalletClientObserver> observer) { | |
| 165 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); | |
| 166 DCHECK(observer); | |
| 167 DCHECK(pending_request_body_.empty()); | |
| 168 request_type_ = GET_FULL_WALLET; | |
| 169 observer_ = observer; | |
| 170 | |
| 171 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); | |
| 172 pending_request_body_.SetString(kRiskParamsKey, GetRiskParams()); | |
| 173 pending_request_body_.SetString(kSelectedInstrumentIdKey, instrument_id); | |
| 174 pending_request_body_.SetString(kSelectedAddressIdKey, address_id); | |
| 175 pending_request_body_.SetString(kMerchantDomainKey, | |
| 176 source_url.GetWithEmptyPath().spec()); | |
| 177 pending_request_body_.SetString(kGoogleTransactionIdKey, | |
| 178 google_transaction_id); | |
| 179 pending_request_body_.Set(kCartKey, cart.ToDictionary().release()); | |
| 180 | |
| 181 crypto::RandBytes(&(one_time_pad_[0]), one_time_pad_.size()); | |
| 182 encryption_escrow_client_.EncryptOneTimePad(one_time_pad_, | |
| 183 weak_ptr_factory_.GetWeakPtr()); | |
| 184 } | |
| 185 | |
| 186 void WalletClient::GetWalletItems( | |
| 187 const GURL& source_url, | |
| 188 base::WeakPtr<WalletClientObserver> observer) { | |
| 189 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); | |
| 190 request_type_ = GET_WALLET_ITEMS; | |
| 191 | |
| 192 base::DictionaryValue request_dict; | |
| 193 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey()); | |
| 194 request_dict.SetString(kRiskParamsKey, GetRiskParams()); | |
| 195 request_dict.SetString(kMerchantDomainKey, | |
| 196 source_url.GetWithEmptyPath().spec()); | |
| 197 | |
| 198 std::string post_body; | |
| 199 base::JSONWriter::Write(&request_dict, &post_body); | |
| 200 | |
| 201 MakeWalletRequest(GetGetWalletItemsUrl(), post_body, observer); | |
| 202 } | |
| 203 | |
| 204 void WalletClient::SaveAddress(const Address& shipping_address, | |
| 205 const GURL& source_url, | |
| 206 base::WeakPtr<WalletClientObserver> observer) { | |
| 207 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); | |
| 208 request_type_ = SAVE_ADDRESS; | |
| 209 | |
| 210 base::DictionaryValue request_dict; | |
| 211 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey()); | |
| 212 request_dict.SetString(kRiskParamsKey, GetRiskParams()); | |
| 213 request_dict.SetString(kMerchantDomainKey, | |
| 214 source_url.GetWithEmptyPath().spec()); | |
| 215 | |
| 216 request_dict.Set(kShippingAddressKey, | |
| 217 shipping_address.ToDictionaryWithID().release()); | |
| 218 | |
| 219 std::string post_body; | |
| 220 base::JSONWriter::Write(&request_dict, &post_body); | |
| 221 | |
| 222 MakeWalletRequest(GetSaveToWalletUrl(), post_body, observer); | |
| 223 } | |
| 224 | |
| 225 void WalletClient::SaveInstrument( | |
| 226 const Instrument& instrument, | |
| 227 const std::string& obfuscated_gaia_id, | |
| 228 const GURL& source_url, | |
| 229 base::WeakPtr<WalletClientObserver> observer) { | |
| 230 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); | |
| 231 DCHECK(observer); | |
| 232 DCHECK(pending_request_body_.empty()); | |
| 233 request_type_ = SAVE_INSTRUMENT; | |
| 234 observer_ = observer; | |
| 235 | |
| 236 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); | |
| 237 pending_request_body_.SetString(kRiskParamsKey, GetRiskParams()); | |
| 238 pending_request_body_.SetString(kMerchantDomainKey, | |
| 239 source_url.GetWithEmptyPath().spec()); | |
| 240 | |
| 241 pending_request_body_.Set(kInstrumentKey, | |
| 242 instrument.ToDictionary().release()); | |
| 243 pending_request_body_.SetString(kInstrumentPhoneNumberKey, | |
| 244 instrument.address().phone_number()); | |
| 245 | |
| 246 encryption_escrow_client_.EscrowInstrumentInformation( | |
| 247 instrument, | |
| 248 obfuscated_gaia_id, | |
| 249 weak_ptr_factory_.GetWeakPtr()); | |
| 250 } | |
| 251 | |
| 252 void WalletClient::SaveInstrumentAndAddress( | |
| 253 const Instrument& instrument, | |
| 254 const Address& address, | |
| 255 const std::string& obfuscated_gaia_id, | |
| 256 const GURL& source_url, | |
| 257 base::WeakPtr<WalletClientObserver> observer) { | |
| 258 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); | |
| 259 DCHECK(observer); | |
| 260 DCHECK(pending_request_body_.empty()); | |
| 261 request_type_ = SAVE_INSTRUMENT_AND_ADDRESS; | |
| 262 observer_ = observer; | |
| 263 | |
| 264 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); | |
| 265 pending_request_body_.SetString(kRiskParamsKey, GetRiskParams()); | |
| 266 pending_request_body_.SetString(kMerchantDomainKey, | |
| 267 source_url.GetWithEmptyPath().spec()); | |
| 268 | |
| 269 pending_request_body_.Set(kInstrumentKey, | |
| 270 instrument.ToDictionary().release()); | |
| 271 pending_request_body_.SetString(kInstrumentPhoneNumberKey, | |
| 272 instrument.address().phone_number()); | |
| 273 | |
| 274 pending_request_body_.Set(kShippingAddressKey, | |
| 275 address.ToDictionaryWithID().release()); | |
| 276 | |
| 277 encryption_escrow_client_.EscrowInstrumentInformation( | |
| 278 instrument, | |
| 279 obfuscated_gaia_id, | |
| 280 weak_ptr_factory_.GetWeakPtr()); | |
| 281 } | |
| 282 | |
| 283 void WalletClient::SendAutocheckoutStatus( | |
| 284 AutocheckoutStatus status, | |
| 285 const GURL& source_url, | |
| 286 const std::string& google_transaction_id, | |
| 287 base::WeakPtr<WalletClientObserver> observer) { | |
| 288 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); | |
| 289 request_type_ = SEND_STATUS; | |
| 290 | |
| 291 base::DictionaryValue request_dict; | |
| 292 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey()); | |
| 293 bool success = status == SUCCESS; | |
| 294 request_dict.SetBoolean(kSuccessKey, success); | |
| 295 request_dict.SetString(kMerchantDomainKey, | |
| 296 source_url.GetWithEmptyPath().spec()); | |
| 297 if (!success) { | |
| 298 request_dict.SetString(kReasonKey, AutocheckoutStatusToString(status)); | |
| 299 } | |
| 300 request_dict.SetString(kGoogleTransactionIdKey, google_transaction_id); | |
| 301 | |
| 302 std::string post_body; | |
| 303 base::JSONWriter::Write(&request_dict, &post_body); | |
| 304 | |
| 305 MakeWalletRequest(GetSendStatusUrl(), post_body, observer); | |
| 306 } | |
| 307 | |
| 308 void WalletClient::UpdateInstrument( | |
| 309 const std::string& instrument_id, | |
| 310 const Address& billing_address, | |
| 311 const GURL& source_url, | |
| 312 base::WeakPtr<WalletClientObserver> observer) { | |
| 313 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); | |
| 314 request_type_ = UPDATE_INSTRUMENT; | |
| 315 | |
| 316 base::DictionaryValue request_dict; | |
| 317 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey()); | |
| 318 request_dict.SetString(kRiskParamsKey, GetRiskParams()); | |
| 319 request_dict.SetString(kMerchantDomainKey, | |
| 320 source_url.GetWithEmptyPath().spec()); | |
| 321 | |
| 322 request_dict.SetString(kUpgradedInstrumentIdKey, instrument_id); | |
| 323 request_dict.SetString(kInstrumentPhoneNumberKey, | |
| 324 billing_address.phone_number()); | |
| 325 request_dict.Set(kUpgradedBillingAddressKey, | |
| 326 billing_address.ToDictionaryWithoutID().release()); | |
| 327 | |
| 328 std::string post_body; | |
| 329 base::JSONWriter::Write(&request_dict, &post_body); | |
| 330 | |
| 331 MakeWalletRequest(GetSaveToWalletUrl(), post_body, observer); | |
| 332 } | |
| 333 | |
| 334 bool WalletClient::HasRequestInProgress() const { | |
| 335 return request_.get() != NULL; | |
| 336 } | |
| 337 | |
| 338 void WalletClient::MakeWalletRequest( | |
| 339 const GURL& url, | |
| 340 const std::string& post_body, | |
| 341 base::WeakPtr<WalletClientObserver> observer) { | |
| 342 DCHECK(!HasRequestInProgress()); | |
| 343 DCHECK(observer); | |
| 344 | |
| 345 observer_ = observer; | |
| 346 | |
| 347 request_.reset(net::URLFetcher::Create( | |
| 348 0, url, net::URLFetcher::POST, this)); | |
| 349 request_->SetRequestContext(context_getter_); | |
| 350 DVLOG(1) << "url=" << url << ", post_body=" << post_body; | |
| 351 request_->SetUploadData(kJsonMimeType, post_body); | |
| 352 request_->Start(); | |
| 353 } | |
| 354 | |
| 355 // TODO(ahutter): Add manual retry logic if it's necessary. | |
| 356 void WalletClient::OnURLFetchComplete( | |
| 357 const net::URLFetcher* source) { | |
| 358 scoped_ptr<net::URLFetcher> old_request = request_.Pass(); | |
| 359 DCHECK_EQ(source, old_request.get()); | |
| 360 DVLOG(1) << "Got response from " << source->GetOriginalURL(); | |
| 361 | |
| 362 std::string data; | |
| 363 source->GetResponseAsString(&data); | |
| 364 DVLOG(1) << "Response body: " << data; | |
| 365 | |
| 366 scoped_ptr<base::DictionaryValue> response_dict; | |
| 367 | |
| 368 int response_code = source->GetResponseCode(); | |
| 369 switch (response_code) { | |
| 370 // HTTP_BAD_REQUEST means the arguments are invalid. No point retrying. | |
| 371 case net::HTTP_BAD_REQUEST: { | |
| 372 request_type_ = NO_PENDING_REQUEST; | |
| 373 observer_->OnWalletError(); | |
| 374 return; | |
| 375 } | |
| 376 // HTTP_OK holds a valid response and HTTP_INTERNAL_SERVER_ERROR holds an | |
| 377 // error code and message for the user. | |
| 378 case net::HTTP_OK: | |
| 379 case net::HTTP_INTERNAL_SERVER_ERROR: { | |
| 380 scoped_ptr<Value> message_value(base::JSONReader::Read(data)); | |
| 381 if (message_value.get() && | |
| 382 message_value->IsType(Value::TYPE_DICTIONARY)) { | |
| 383 response_dict.reset( | |
| 384 static_cast<base::DictionaryValue*>(message_value.release())); | |
| 385 } | |
| 386 if (response_code == net::HTTP_INTERNAL_SERVER_ERROR) { | |
| 387 request_type_ = NO_PENDING_REQUEST; | |
| 388 // TODO(ahutter): Do something with the response. See | |
| 389 // http://crbug.com/164410. | |
| 390 observer_->OnWalletError(); | |
| 391 return; | |
| 392 } | |
| 393 break; | |
| 394 } | |
| 395 // Anything else is an error. | |
| 396 default: { | |
| 397 request_type_ = NO_PENDING_REQUEST; | |
| 398 observer_->OnNetworkError(response_code); | |
| 399 return; | |
| 400 } | |
| 401 } | |
| 402 | |
| 403 RequestType type = request_type_; | |
| 404 request_type_ = NO_PENDING_REQUEST; | |
| 405 | |
| 406 if (!(type == ACCEPT_LEGAL_DOCUMENTS || type == SEND_STATUS) && | |
| 407 !response_dict) { | |
| 408 HandleMalformedResponse(old_request.get()); | |
| 409 return; | |
| 410 } | |
| 411 | |
| 412 switch (type) { | |
| 413 case ACCEPT_LEGAL_DOCUMENTS: | |
| 414 if (observer_) | |
| 415 observer_->OnDidAcceptLegalDocuments(); | |
| 416 break; | |
| 417 | |
| 418 case AUTHENTICATE_INSTRUMENT: { | |
| 419 std::string auth_result; | |
| 420 if (response_dict->GetString(kAuthResultKey, &auth_result)) { | |
| 421 std::string trimmed; | |
| 422 TrimWhitespaceASCII(auth_result, | |
| 423 TRIM_ALL, | |
| 424 &trimmed); | |
| 425 if (observer_) { | |
| 426 observer_->OnDidAuthenticateInstrument( | |
| 427 LowerCaseEqualsASCII(trimmed, "success")); | |
| 428 } | |
| 429 } else { | |
| 430 HandleMalformedResponse(old_request.get()); | |
| 431 } | |
| 432 break; | |
| 433 } | |
| 434 | |
| 435 case SEND_STATUS: | |
| 436 if (observer_) | |
| 437 observer_->OnDidSendAutocheckoutStatus(); | |
| 438 break; | |
| 439 | |
| 440 case GET_FULL_WALLET: { | |
| 441 scoped_ptr<FullWallet> full_wallet( | |
| 442 FullWallet::CreateFullWallet(*response_dict)); | |
| 443 if (full_wallet) { | |
| 444 full_wallet->set_one_time_pad(one_time_pad_); | |
| 445 if (observer_) | |
| 446 observer_->OnDidGetFullWallet(full_wallet.Pass()); | |
| 447 } else { | |
| 448 HandleMalformedResponse(old_request.get()); | |
| 449 } | |
| 450 break; | |
| 451 } | |
| 452 | |
| 453 case GET_WALLET_ITEMS: { | |
| 454 scoped_ptr<WalletItems> wallet_items( | |
| 455 WalletItems::CreateWalletItems(*response_dict)); | |
| 456 if (wallet_items) { | |
| 457 if (observer_) | |
| 458 observer_->OnDidGetWalletItems(wallet_items.Pass()); | |
| 459 } else { | |
| 460 HandleMalformedResponse(old_request.get()); | |
| 461 } | |
| 462 break; | |
| 463 } | |
| 464 | |
| 465 case SAVE_ADDRESS: { | |
| 466 std::string shipping_address_id; | |
| 467 std::vector<RequiredAction> required_actions; | |
| 468 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions); | |
| 469 if (response_dict->GetString(kShippingAddressIdKey, | |
| 470 &shipping_address_id) || | |
| 471 !required_actions.empty()) { | |
| 472 if (observer_) | |
| 473 observer_->OnDidSaveAddress(shipping_address_id, required_actions); | |
| 474 } else { | |
| 475 HandleMalformedResponse(old_request.get()); | |
| 476 } | |
| 477 break; | |
| 478 } | |
| 479 | |
| 480 case SAVE_INSTRUMENT: { | |
| 481 std::string instrument_id; | |
| 482 std::vector<RequiredAction> required_actions; | |
| 483 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions); | |
| 484 if (response_dict->GetString(kInstrumentIdKey, &instrument_id) || | |
| 485 !required_actions.empty()) { | |
| 486 if (observer_) | |
| 487 observer_->OnDidSaveInstrument(instrument_id, required_actions); | |
| 488 } else { | |
| 489 HandleMalformedResponse(old_request.get()); | |
| 490 } | |
| 491 break; | |
| 492 } | |
| 493 | |
| 494 case SAVE_INSTRUMENT_AND_ADDRESS: { | |
| 495 std::string instrument_id; | |
| 496 response_dict->GetString(kInstrumentIdKey, &instrument_id); | |
| 497 std::string shipping_address_id; | |
| 498 response_dict->GetString(kShippingAddressIdKey, | |
| 499 &shipping_address_id); | |
| 500 std::vector<RequiredAction> required_actions; | |
| 501 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions); | |
| 502 if ((!instrument_id.empty() && !shipping_address_id.empty()) || | |
| 503 !required_actions.empty()) { | |
| 504 if (observer_) { | |
| 505 observer_->OnDidSaveInstrumentAndAddress( | |
| 506 instrument_id, | |
| 507 shipping_address_id, | |
| 508 required_actions); | |
| 509 } | |
| 510 } else { | |
| 511 HandleMalformedResponse(old_request.get()); | |
| 512 } | |
| 513 break; | |
| 514 } | |
| 515 | |
| 516 case UPDATE_INSTRUMENT: { | |
| 517 std::string instrument_id; | |
| 518 std::vector<RequiredAction> required_actions; | |
| 519 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions); | |
| 520 if (response_dict->GetString(kInstrumentIdKey, &instrument_id) || | |
| 521 !required_actions.empty()) { | |
| 522 if (observer_) | |
| 523 observer_->OnDidUpdateInstrument(instrument_id, required_actions); | |
| 524 } else { | |
| 525 HandleMalformedResponse(old_request.get()); | |
| 526 } | |
| 527 break; | |
| 528 } | |
| 529 | |
| 530 case NO_PENDING_REQUEST: | |
| 531 NOTREACHED(); | |
| 532 } | |
| 533 } | |
| 534 | |
| 535 void WalletClient::HandleMalformedResponse(net::URLFetcher* request) { | |
| 536 // Called to inform exponential backoff logic of the error. | |
| 537 request->ReceivedContentWasMalformed(); | |
| 538 if (observer_) | |
| 539 observer_->OnMalformedResponse(); | |
| 540 } | |
| 541 | |
| 542 void WalletClient::OnDidEncryptOneTimePad( | |
| 543 const std::string& encrypted_one_time_pad, | |
| 544 const std::string& session_material) { | |
| 545 DCHECK_EQ(GET_FULL_WALLET, request_type_); | |
| 546 pending_request_body_.SetString(kEncryptedOtpKey, encrypted_one_time_pad); | |
| 547 pending_request_body_.SetString(kSessionMaterialKey, session_material); | |
| 548 | |
| 549 std::string post_body; | |
| 550 base::JSONWriter::Write(&pending_request_body_, &post_body); | |
| 551 pending_request_body_.Clear(); | |
| 552 | |
| 553 MakeWalletRequest(GetGetFullWalletUrl(), post_body, observer_); | |
| 554 } | |
| 555 | |
| 556 void WalletClient::OnDidEscrowInstrumentInformation( | |
| 557 const std::string& escrow_handle) { | |
| 558 DCHECK(request_type_ == SAVE_INSTRUMENT || | |
| 559 request_type_ == SAVE_INSTRUMENT_AND_ADDRESS); | |
| 560 | |
| 561 pending_request_body_.SetString(kInstrumentEscrowHandleKey, escrow_handle); | |
| 562 | |
| 563 std::string post_body; | |
| 564 base::JSONWriter::Write(&pending_request_body_, &post_body); | |
| 565 pending_request_body_.Clear(); | |
| 566 | |
| 567 MakeWalletRequest(GetSaveToWalletUrl(), post_body, observer_); | |
| 568 } | |
| 569 | |
| 570 void WalletClient::OnDidEscrowCardVerificationNumber( | |
| 571 const std::string& escrow_handle) { | |
| 572 DCHECK_EQ(AUTHENTICATE_INSTRUMENT, request_type_); | |
| 573 pending_request_body_.SetString(kInstrumentEscrowHandleKey, escrow_handle); | |
| 574 | |
| 575 std::string post_body; | |
| 576 base::JSONWriter::Write(&pending_request_body_, &post_body); | |
| 577 pending_request_body_.Clear(); | |
| 578 | |
| 579 MakeWalletRequest(GetAuthenticateInstrumentUrl(), post_body, observer_); | |
| 580 } | |
| 581 | |
| 582 void WalletClient::OnNetworkError(int response_code) { | |
| 583 if (observer_) | |
| 584 observer_->OnNetworkError(response_code); | |
| 585 } | |
| 586 | |
| 587 void WalletClient::OnMalformedResponse() { | |
| 588 if (observer_) | |
| 589 observer_->OnMalformedResponse(); | |
| 590 } | |
| 591 | |
| 592 } // namespace wallet | |
| 593 } // namespace autofill | |
| OLD | NEW |