Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: components/autofill/content/browser/wallet/wallet_client.cc

Issue 17970003: New encryption/escrow endpoints for Wallet (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebasing again... Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "components/autofill/content/browser/wallet/wallet_client.h" 5 #include "components/autofill/content/browser/wallet/wallet_client.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/json/json_reader.h" 8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversions.h"
13 #include "components/autofill/content/browser/wallet/form_field_error.h" 16 #include "components/autofill/content/browser/wallet/form_field_error.h"
14 #include "components/autofill/content/browser/wallet/instrument.h" 17 #include "components/autofill/content/browser/wallet/instrument.h"
15 #include "components/autofill/content/browser/wallet/wallet_address.h" 18 #include "components/autofill/content/browser/wallet/wallet_address.h"
16 #include "components/autofill/content/browser/wallet/wallet_client_delegate.h" 19 #include "components/autofill/content/browser/wallet/wallet_client_delegate.h"
17 #include "components/autofill/content/browser/wallet/wallet_items.h" 20 #include "components/autofill/content/browser/wallet/wallet_items.h"
18 #include "components/autofill/content/browser/wallet/wallet_service_url.h" 21 #include "components/autofill/content/browser/wallet/wallet_service_url.h"
19 #include "components/autofill/core/browser/autofill_metrics.h" 22 #include "components/autofill/core/browser/autofill_metrics.h"
20 #include "crypto/random.h" 23 #include "crypto/random.h"
21 #include "google_apis/google_api_keys.h" 24 #include "google_apis/google_api_keys.h"
25 #include "net/base/escape.h"
22 #include "net/http/http_status_code.h" 26 #include "net/http/http_status_code.h"
23 #include "net/url_request/url_fetcher.h" 27 #include "net/url_request/url_fetcher.h"
24 #include "net/url_request/url_request_context_getter.h" 28 #include "net/url_request/url_request_context_getter.h"
25 29
26 // TODO(ahutter): Change all VLOGs to DVLOGs after dogfood. 30 // TODO(ahutter): Change all VLOGs to DVLOGs after dogfood.
27 namespace autofill { 31 namespace autofill {
28 namespace wallet { 32 namespace wallet {
29 33
30 namespace { 34 namespace {
31 35
36 const char kFormEncodedMimeType[] = "application/x-www-form-urlencoded";
32 const char kJsonMimeType[] = "application/json"; 37 const char kJsonMimeType[] = "application/json";
38 const char kEscrowNewInstrumentFormat[] =
39 "request_content_type=application/json&request=%s&cvn=%s&card_number=%s";
40 const char kEscrowCardVerificationNumberFormat[] =
41 "request_content_type=application/json&request=%s&cvn=%s";
42 const char kGetFullWalletRequestFormat[] =
43 "request_content_type=application/json&request=%s&otp=%s:%s";
33 const size_t kOneTimePadLength = 6; 44 const size_t kOneTimePadLength = 6;
34 45
46 // The maximum number of bits in the one time pad that the server is willing to
47 // accept.
48 const size_t kMaxBits = 56;
49
50 // The minimum number of bits in the one time pad that the server is willing to
51 // accept.
52 const size_t kMinBits = 40;
53
35 std::string AutocheckoutStatusToString(AutocheckoutStatus status) { 54 std::string AutocheckoutStatusToString(AutocheckoutStatus status) {
36 switch (status) { 55 switch (status) {
37 case MISSING_FIELDMAPPING: 56 case MISSING_FIELDMAPPING:
38 return "MISSING_FIELDMAPPING"; 57 return "MISSING_FIELDMAPPING";
39 case MISSING_ADVANCE: 58 case MISSING_ADVANCE:
40 return "MISSING_ADVANCE"; 59 return "MISSING_ADVANCE";
41 case MISSING_CLICK_ELEMENT_BEFORE_FORM_FILLING: 60 case MISSING_CLICK_ELEMENT_BEFORE_FORM_FILLING:
42 return "MISSING_CLICK_ELEMENT_BEFORE_FORM_FILLING"; 61 return "MISSING_CLICK_ELEMENT_BEFORE_FORM_FILLING";
43 case MISSING_CLICK_ELEMENT_AFTER_FORM_FILLING: 62 case MISSING_CLICK_ELEMENT_AFTER_FORM_FILLING:
44 return "MISSING_CLICK_ELEMENT_AFTER_FORM_FILLING"; 63 return "MISSING_CLICK_ELEMENT_AFTER_FORM_FILLING";
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 const std::string& google_transaction_id, 253 const std::string& google_transaction_id,
235 const std::vector<RiskCapability> risk_capabilities) 254 const std::vector<RiskCapability> risk_capabilities)
236 : instrument_id(instrument_id), 255 : instrument_id(instrument_id),
237 address_id(address_id), 256 address_id(address_id),
238 source_url(source_url), 257 source_url(source_url),
239 google_transaction_id(google_transaction_id), 258 google_transaction_id(google_transaction_id),
240 risk_capabilities(risk_capabilities) {} 259 risk_capabilities(risk_capabilities) {}
241 260
242 WalletClient::FullWalletRequest::~FullWalletRequest() {} 261 WalletClient::FullWalletRequest::~FullWalletRequest() {}
243 262
244 WalletClient::UpdateInstrumentRequest::UpdateInstrumentRequest(
245 const std::string& instrument_id,
246 const GURL& source_url)
247 : instrument_id(instrument_id),
248 expiration_month(0),
249 expiration_year(0),
250 source_url(source_url) {}
251
252 WalletClient::UpdateInstrumentRequest::~UpdateInstrumentRequest() {}
253
254 WalletClient::WalletClient(net::URLRequestContextGetter* context_getter, 263 WalletClient::WalletClient(net::URLRequestContextGetter* context_getter,
255 WalletClientDelegate* delegate) 264 WalletClientDelegate* delegate)
256 : context_getter_(context_getter), 265 : context_getter_(context_getter),
257 delegate_(delegate), 266 delegate_(delegate),
258 request_type_(NO_PENDING_REQUEST), 267 request_type_(NO_PENDING_REQUEST),
259 one_time_pad_(kOneTimePadLength), 268 one_time_pad_(kOneTimePadLength) {
260 encryption_escrow_client_(context_getter, this) {
261 DCHECK(context_getter_.get()); 269 DCHECK(context_getter_.get());
262 DCHECK(delegate_); 270 DCHECK(delegate_);
263 } 271 }
264 272
265 WalletClient::~WalletClient() {} 273 WalletClient::~WalletClient() {}
266 274
267 void WalletClient::AcceptLegalDocuments( 275 void WalletClient::AcceptLegalDocuments(
268 const std::vector<WalletItems::LegalDocument*>& documents, 276 const std::vector<WalletItems::LegalDocument*>& documents,
269 const std::string& google_transaction_id, 277 const std::string& google_transaction_id,
270 const GURL& source_url) { 278 const GURL& source_url) {
271 if (documents.empty()) 279 if (documents.empty())
272 return; 280 return;
273 281
274 std::vector<std::string> document_ids; 282 std::vector<std::string> document_ids;
275 for (size_t i = 0; i < documents.size(); ++i) { 283 for (size_t i = 0; i < documents.size(); ++i) {
276 document_ids.push_back(documents[i]->id()); 284 document_ids.push_back(documents[i]->id());
277 } 285 }
278 DoAcceptLegalDocuments(document_ids, google_transaction_id, source_url); 286 DoAcceptLegalDocuments(document_ids, google_transaction_id, source_url);
279 } 287 }
280 288
281 void WalletClient::AuthenticateInstrument( 289 void WalletClient::AuthenticateInstrument(
282 const std::string& instrument_id, 290 const std::string& instrument_id,
283 const std::string& card_verification_number, 291 const std::string& card_verification_number) {
284 const std::string& obfuscated_gaia_id) {
285 if (HasRequestInProgress()) { 292 if (HasRequestInProgress()) {
286 pending_requests_.push(base::Bind(&WalletClient::AuthenticateInstrument, 293 pending_requests_.push(base::Bind(&WalletClient::AuthenticateInstrument,
287 base::Unretained(this), 294 base::Unretained(this),
288 instrument_id, 295 instrument_id,
289 card_verification_number, 296 card_verification_number));
290 obfuscated_gaia_id));
291 return; 297 return;
292 } 298 }
293 299
294 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); 300 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
295 DCHECK(pending_request_body_.empty());
296 request_type_ = AUTHENTICATE_INSTRUMENT; 301 request_type_ = AUTHENTICATE_INSTRUMENT;
297 302
298 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); 303 base::DictionaryValue request_dict;
299 pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData()); 304 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
300 pending_request_body_.SetString(kInstrumentIdKey, instrument_id); 305 request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData());
306 request_dict.SetString(kInstrumentIdKey, instrument_id);
301 307
302 encryption_escrow_client_.EscrowCardVerificationNumber( 308 std::string json_payload;
303 card_verification_number, obfuscated_gaia_id); 309 base::JSONWriter::Write(&request_dict, &json_payload);
310
311 std::string escaped_card_verification_number = net::EscapeUrlEncodedData(
312 card_verification_number, true);
313
314 std::string post_body = base::StringPrintf(
315 kEscrowCardVerificationNumberFormat,
316 net::EscapeUrlEncodedData(json_payload, true).c_str(),
317 escaped_card_verification_number.c_str());
318
319 MakeWalletRequest(GetAuthenticateInstrumentUrl(),
320 post_body,
321 kFormEncodedMimeType);
304 } 322 }
305 323
306 void WalletClient::GetFullWallet(const FullWalletRequest& full_wallet_request) { 324 void WalletClient::GetFullWallet(const FullWalletRequest& full_wallet_request) {
307 if (HasRequestInProgress()) { 325 if (HasRequestInProgress()) {
308 pending_requests_.push(base::Bind(&WalletClient::GetFullWallet, 326 pending_requests_.push(base::Bind(&WalletClient::GetFullWallet,
309 base::Unretained(this), 327 base::Unretained(this),
310 full_wallet_request)); 328 full_wallet_request));
311 return; 329 return;
312 } 330 }
313 331
314 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); 332 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
315 DCHECK(pending_request_body_.empty());
316 request_type_ = GET_FULL_WALLET; 333 request_type_ = GET_FULL_WALLET;
317 334
318 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); 335 base::DictionaryValue request_dict;
319 pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData()); 336 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
320 pending_request_body_.SetString(kSelectedInstrumentIdKey, 337 request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData());
321 full_wallet_request.instrument_id); 338 request_dict.SetString(kSelectedInstrumentIdKey,
322 pending_request_body_.SetString(kSelectedAddressIdKey, 339 full_wallet_request.instrument_id);
323 full_wallet_request.address_id); 340 request_dict.SetString(kSelectedAddressIdKey, full_wallet_request.address_id);
324 pending_request_body_.SetString( 341 request_dict.SetString(
325 kMerchantDomainKey, 342 kMerchantDomainKey,
326 full_wallet_request.source_url.GetWithEmptyPath().spec()); 343 full_wallet_request.source_url.GetWithEmptyPath().spec());
327 pending_request_body_.SetString(kGoogleTransactionIdKey, 344 request_dict.SetString(kGoogleTransactionIdKey,
328 full_wallet_request.google_transaction_id); 345 full_wallet_request.google_transaction_id);
329 pending_request_body_.SetString( 346 request_dict.SetString(kFeatureKey,
330 kFeatureKey, 347 DialogTypeToFeatureString(delegate_->GetDialogType()));
331 DialogTypeToFeatureString(delegate_->GetDialogType()));
332 348
333 scoped_ptr<base::ListValue> risk_capabilities_list(new base::ListValue()); 349 scoped_ptr<base::ListValue> risk_capabilities_list(new base::ListValue());
334 for (std::vector<RiskCapability>::const_iterator it = 350 for (std::vector<RiskCapability>::const_iterator it =
335 full_wallet_request.risk_capabilities.begin(); 351 full_wallet_request.risk_capabilities.begin();
336 it != full_wallet_request.risk_capabilities.end(); 352 it != full_wallet_request.risk_capabilities.end();
337 ++it) { 353 ++it) {
338 risk_capabilities_list->AppendString(RiskCapabilityToString(*it)); 354 risk_capabilities_list->AppendString(RiskCapabilityToString(*it));
339 } 355 }
340 pending_request_body_.Set(kRiskCapabilitiesKey, 356 request_dict.Set(kRiskCapabilitiesKey, risk_capabilities_list.release());
341 risk_capabilities_list.release()); 357
358 std::string json_payload;
359 base::JSONWriter::Write(&request_dict, &json_payload);
342 360
343 crypto::RandBytes(&(one_time_pad_[0]), one_time_pad_.size()); 361 crypto::RandBytes(&(one_time_pad_[0]), one_time_pad_.size());
344 encryption_escrow_client_.EncryptOneTimePad(one_time_pad_); 362
363 size_t num_bits = one_time_pad_.size() * 8;
364 DCHECK_LE(num_bits, kMaxBits);
365 DCHECK_GE(num_bits, kMinBits);
366
367 std::string post_body = base::StringPrintf(
368 kGetFullWalletRequestFormat,
369 net::EscapeUrlEncodedData(json_payload, true).c_str(),
370 base::HexEncode(&num_bits, 1).c_str(),
371 base::HexEncode(&(one_time_pad_[0]), one_time_pad_.size()).c_str());
372
373 MakeWalletRequest(GetGetFullWalletUrl(), post_body, kFormEncodedMimeType);
345 } 374 }
346 375
347 void WalletClient::GetWalletItems(const GURL& source_url) { 376 void WalletClient::SaveToWallet(scoped_ptr<Instrument> instrument,
377 scoped_ptr<Address> address,
378 const GURL& source_url) {
379 DCHECK(instrument || address);
348 if (HasRequestInProgress()) { 380 if (HasRequestInProgress()) {
349 pending_requests_.push(base::Bind(&WalletClient::GetWalletItems, 381 pending_requests_.push(base::Bind(&WalletClient::SaveToWallet,
350 base::Unretained(this), 382 base::Unretained(this),
383 base::Passed(&instrument),
384 base::Passed(&address),
351 source_url)); 385 source_url));
352 return; 386 return;
353 } 387 }
354 388
355 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); 389 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
356 request_type_ = GET_WALLET_ITEMS; 390 request_type_ = SAVE_TO_WALLET;
357 391
358 base::DictionaryValue request_dict; 392 base::DictionaryValue request_dict;
359 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey()); 393 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
360 request_dict.SetString(kMerchantDomainKey,
361 source_url.GetWithEmptyPath().spec());
362
363 std::string post_body;
364 base::JSONWriter::Write(&request_dict, &post_body);
365
366 MakeWalletRequest(GetGetWalletItemsUrl(), post_body);
367 }
368
369 void WalletClient::SaveAddress(const Address& shipping_address,
370 const GURL& source_url) {
371 if (HasRequestInProgress()) {
372 pending_requests_.push(base::Bind(&WalletClient::SaveAddress,
373 base::Unretained(this),
374 shipping_address,
375 source_url));
376 return;
377 }
378
379 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
380 request_type_ = SAVE_ADDRESS;
381
382 base::DictionaryValue request_dict;
383 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
384 request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData()); 394 request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData());
385 request_dict.SetString(kMerchantDomainKey, 395 request_dict.SetString(kMerchantDomainKey,
386 source_url.GetWithEmptyPath().spec()); 396 source_url.GetWithEmptyPath().spec());
387 397
388 request_dict.Set(kShippingAddressKey, 398 std::string primary_account_number;
389 shipping_address.ToDictionaryWithID().release()); 399 std::string card_verification_number;
400 if (instrument) {
401 primary_account_number = net::EscapeUrlEncodedData(
402 UTF16ToUTF8(instrument->primary_account_number()), true);
403 card_verification_number = net::EscapeUrlEncodedData(
404 UTF16ToUTF8(instrument->card_verification_number()), true);
390 405
391 std::string post_body; 406 if (instrument->object_id().empty()) {
392 base::JSONWriter::Write(&request_dict, &post_body); 407 request_dict.Set(kInstrumentKey, instrument->ToDictionary().release());
408 request_dict.SetString(kInstrumentPhoneNumberKey,
409 instrument->address()->phone_number());
410 } else {
411 DCHECK(instrument->address() ||
412 (instrument->expiration_month() > 0 &&
413 instrument->expiration_year() > 0));
393 414
394 MakeWalletRequest(GetSaveToWalletUrl(), post_body); 415 request_dict.SetString(kUpgradedInstrumentIdKey,
416 instrument->object_id());
417
418 if (instrument->address()) {
419 request_dict.SetString(kInstrumentPhoneNumberKey,
420 instrument->address()->phone_number());
421 request_dict.Set(
422 kUpgradedBillingAddressKey,
423 instrument->address()->ToDictionaryWithoutID().release());
424 }
425
426 if (instrument->expiration_month() > 0 &&
427 instrument->expiration_year() > 0) {
428 DCHECK(!instrument->card_verification_number().empty());
429 request_dict.SetInteger(kInstrumentExpMonthKey,
430 instrument->expiration_month());
431 request_dict.SetInteger(kInstrumentExpYearKey,
432 instrument->expiration_year());
433 }
434
435 if (request_dict.HasKey(kInstrumentKey))
436 request_dict.SetString(kInstrumentType, "CREDIT_CARD");
437 }
438 }
439 if (address) {
440 request_dict.Set(kShippingAddressKey,
441 address->ToDictionaryWithID().release());
442 }
443
444 std::string json_payload;
445 base::JSONWriter::Write(&request_dict, &json_payload);
446
447 if (!card_verification_number.empty()) {
448 std::string post_body;
449 if (!primary_account_number.empty()) {
450 post_body = base::StringPrintf(
451 kEscrowNewInstrumentFormat,
452 net::EscapeUrlEncodedData(json_payload, true).c_str(),
453 card_verification_number.c_str(),
454 primary_account_number.c_str());
455 } else {
456 post_body = base::StringPrintf(
457 kEscrowCardVerificationNumberFormat,
458 net::EscapeUrlEncodedData(json_payload, true).c_str(),
459 card_verification_number.c_str());
460 }
461 MakeWalletRequest(GetSaveToWalletUrl(), post_body, kFormEncodedMimeType);
462 } else {
463 MakeWalletRequest(GetSaveToWalletNoEscrowUrl(),
464 json_payload,
465 kJsonMimeType);
466 }
395 } 467 }
396 468
397 void WalletClient::SaveInstrument( 469 void WalletClient::GetWalletItems(const GURL& source_url) {
398 const Instrument& instrument,
399 const std::string& obfuscated_gaia_id,
400 const GURL& source_url) {
401 if (HasRequestInProgress()) { 470 if (HasRequestInProgress()) {
402 pending_requests_.push(base::Bind(&WalletClient::SaveInstrument, 471 pending_requests_.push(base::Bind(&WalletClient::GetWalletItems,
403 base::Unretained(this), 472 base::Unretained(this),
404 instrument,
405 obfuscated_gaia_id,
406 source_url)); 473 source_url));
407 return; 474 return;
408 } 475 }
409 476
410 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); 477 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
411 DCHECK(pending_request_body_.empty()); 478 request_type_ = GET_WALLET_ITEMS;
412 request_type_ = SAVE_INSTRUMENT;
413 479
414 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); 480 base::DictionaryValue request_dict;
415 pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData()); 481 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
416 pending_request_body_.SetString(kMerchantDomainKey, 482 request_dict.SetString(kMerchantDomainKey,
417 source_url.GetWithEmptyPath().spec()); 483 source_url.GetWithEmptyPath().spec());
418 484
419 pending_request_body_.Set(kInstrumentKey, 485 std::string post_body;
420 instrument.ToDictionary().release()); 486 base::JSONWriter::Write(&request_dict, &post_body);
421 pending_request_body_.SetString(kInstrumentPhoneNumberKey,
422 instrument.address().phone_number());
423 487
424 encryption_escrow_client_.EscrowInstrumentInformation(instrument, 488 MakeWalletRequest(GetGetWalletItemsUrl(), post_body, kJsonMimeType);
425 obfuscated_gaia_id);
426 }
427
428 void WalletClient::SaveInstrumentAndAddress(
429 const Instrument& instrument,
430 const Address& address,
431 const std::string& obfuscated_gaia_id,
432 const GURL& source_url) {
433 if (HasRequestInProgress()) {
434 pending_requests_.push(base::Bind(&WalletClient::SaveInstrumentAndAddress,
435 base::Unretained(this),
436 instrument,
437 address,
438 obfuscated_gaia_id,
439 source_url));
440 return;
441 }
442
443 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
444 DCHECK(pending_request_body_.empty());
445 request_type_ = SAVE_INSTRUMENT_AND_ADDRESS;
446
447 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey());
448 pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData());
449 pending_request_body_.SetString(kMerchantDomainKey,
450 source_url.GetWithEmptyPath().spec());
451
452 pending_request_body_.Set(kInstrumentKey,
453 instrument.ToDictionary().release());
454 pending_request_body_.SetString(kInstrumentPhoneNumberKey,
455 instrument.address().phone_number());
456
457 pending_request_body_.Set(kShippingAddressKey,
458 address.ToDictionaryWithID().release());
459
460 encryption_escrow_client_.EscrowInstrumentInformation(instrument,
461 obfuscated_gaia_id);
462 } 489 }
463 490
464 void WalletClient::SendAutocheckoutStatus( 491 void WalletClient::SendAutocheckoutStatus(
465 AutocheckoutStatus status, 492 AutocheckoutStatus status,
466 const GURL& source_url, 493 const GURL& source_url,
467 const std::vector<AutocheckoutStatistic>& latency_statistics, 494 const std::vector<AutocheckoutStatistic>& latency_statistics,
468 const std::string& google_transaction_id) { 495 const std::string& google_transaction_id) {
469 DVLOG(1) << "Sending Autocheckout Status: " << status 496 DVLOG(1) << "Sending Autocheckout Status: " << status
470 << " for: " << source_url; 497 << " for: " << source_url;
471 if (HasRequestInProgress()) { 498 if (HasRequestInProgress()) {
(...skipping 25 matching lines...) Expand all
497 latency_statistics[i].ToDictionary().release()); 524 latency_statistics[i].ToDictionary().release());
498 } 525 }
499 request_dict.Set(kAutocheckoutStepsKey, 526 request_dict.Set(kAutocheckoutStepsKey,
500 latency_statistics_json.release()); 527 latency_statistics_json.release());
501 } 528 }
502 request_dict.SetString(kGoogleTransactionIdKey, google_transaction_id); 529 request_dict.SetString(kGoogleTransactionIdKey, google_transaction_id);
503 530
504 std::string post_body; 531 std::string post_body;
505 base::JSONWriter::Write(&request_dict, &post_body); 532 base::JSONWriter::Write(&request_dict, &post_body);
506 533
507 MakeWalletRequest(GetSendStatusUrl(), post_body); 534 MakeWalletRequest(GetSendStatusUrl(), post_body, kJsonMimeType);
508 }
509
510 void WalletClient::UpdateAddress(const Address& address,
511 const GURL& source_url) {
512 if (HasRequestInProgress()) {
513 pending_requests_.push(base::Bind(&WalletClient::UpdateAddress,
514 base::Unretained(this),
515 address,
516 source_url));
517 return;
518 }
519
520 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
521 request_type_ = UPDATE_ADDRESS;
522
523 base::DictionaryValue request_dict;
524 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
525 request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData());
526 request_dict.SetString(kMerchantDomainKey,
527 source_url.GetWithEmptyPath().spec());
528
529 request_dict.Set(kShippingAddressKey,
530 address.ToDictionaryWithID().release());
531
532 std::string post_body;
533 base::JSONWriter::Write(&request_dict, &post_body);
534
535 MakeWalletRequest(GetSaveToWalletUrl(), post_body);
536 }
537
538 void WalletClient::UpdateInstrument(
539 const UpdateInstrumentRequest& update_instrument_request,
540 scoped_ptr<Address> billing_address) {
541 if (HasRequestInProgress()) {
542 pending_requests_.push(base::Bind(&WalletClient::UpdateInstrument,
543 base::Unretained(this),
544 update_instrument_request,
545 base::Passed(&billing_address)));
546 return;
547 }
548
549 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
550 DCHECK(pending_request_body_.empty());
551 DCHECK(update_instrument_request.card_verification_number.empty() ==
552 update_instrument_request.obfuscated_gaia_id.empty());
553 DCHECK(billing_address ||
554 (update_instrument_request.expiration_month > 0 &&
555 update_instrument_request.expiration_year > 0));
556
557 request_type_ = UPDATE_INSTRUMENT;
558
559 base::DictionaryValue* active_request_body;
560 base::DictionaryValue request_dict;
561 if (update_instrument_request.card_verification_number.empty())
562 active_request_body = &request_dict;
563 else
564 active_request_body = &pending_request_body_;
565
566 active_request_body->SetString(kApiKeyKey, google_apis::GetAPIKey());
567 active_request_body->SetString(kRiskParamsKey, delegate_->GetRiskData());
568 active_request_body->SetString(
569 kMerchantDomainKey,
570 update_instrument_request.source_url.GetWithEmptyPath().spec());
571
572 active_request_body->SetString(kUpgradedInstrumentIdKey,
573 update_instrument_request.instrument_id);
574
575 if (billing_address) {
576 active_request_body->SetString(kInstrumentPhoneNumberKey,
577 billing_address->phone_number());
578 active_request_body->Set(
579 kUpgradedBillingAddressKey,
580 billing_address->ToDictionaryWithoutID().release());
581 }
582
583 if (update_instrument_request.expiration_month > 0 &&
584 update_instrument_request.expiration_year > 0) {
585 DCHECK(!update_instrument_request.card_verification_number.empty());
586 active_request_body->SetInteger(
587 kInstrumentExpMonthKey,
588 update_instrument_request.expiration_month);
589 active_request_body->SetInteger(kInstrumentExpYearKey,
590 update_instrument_request.expiration_year);
591 }
592
593 if (active_request_body->HasKey(kInstrumentKey))
594 active_request_body->SetString(kInstrumentType, "CREDIT_CARD");
595
596 if (update_instrument_request.card_verification_number.empty()) {
597 std::string post_body;
598 base::JSONWriter::Write(active_request_body, &post_body);
599 MakeWalletRequest(GetSaveToWalletUrl(), post_body);
600 } else {
601 encryption_escrow_client_.EscrowCardVerificationNumber(
602 update_instrument_request.card_verification_number,
603 update_instrument_request.obfuscated_gaia_id);
604 }
605 } 535 }
606 536
607 bool WalletClient::HasRequestInProgress() const { 537 bool WalletClient::HasRequestInProgress() const {
608 // |SaveInstrument*()| and |UpdateInstrument()| methods don't set |request_| 538 return request_;
609 // until sensitive info has been escrowed, so this class is considered to have
610 // a request in progress if |encryption_escrow_client_| is working as well.
611 return request_ || encryption_escrow_client_.HasRequestInProgress();
612 } 539 }
613 540
614 void WalletClient::CancelRequests() { 541 void WalletClient::CancelRequests() {
615 encryption_escrow_client_.CancelRequest();
616 pending_request_body_.Clear();
617 request_.reset(); 542 request_.reset();
618 request_type_ = NO_PENDING_REQUEST; 543 request_type_ = NO_PENDING_REQUEST;
619 while (!pending_requests_.empty()) { 544 while (!pending_requests_.empty()) {
620 pending_requests_.pop(); 545 pending_requests_.pop();
621 } 546 }
622 } 547 }
623 548
624 void WalletClient::DoAcceptLegalDocuments( 549 void WalletClient::DoAcceptLegalDocuments(
625 const std::vector<std::string>& document_ids, 550 const std::vector<std::string>& document_ids,
626 const std::string& google_transaction_id, 551 const std::string& google_transaction_id,
(...skipping 19 matching lines...) Expand all
646 for (std::vector<std::string>::const_iterator it = document_ids.begin(); 571 for (std::vector<std::string>::const_iterator it = document_ids.begin();
647 it != document_ids.end(); ++it) { 572 it != document_ids.end(); ++it) {
648 if (!it->empty()) 573 if (!it->empty())
649 docs_list->AppendString(*it); 574 docs_list->AppendString(*it);
650 } 575 }
651 request_dict.Set(kAcceptedLegalDocumentKey, docs_list.release()); 576 request_dict.Set(kAcceptedLegalDocumentKey, docs_list.release());
652 577
653 std::string post_body; 578 std::string post_body;
654 base::JSONWriter::Write(&request_dict, &post_body); 579 base::JSONWriter::Write(&request_dict, &post_body);
655 580
656 MakeWalletRequest(GetAcceptLegalDocumentsUrl(), post_body); 581 MakeWalletRequest(GetAcceptLegalDocumentsUrl(), post_body, kJsonMimeType);
657 } 582 }
658 583
659 void WalletClient::MakeWalletRequest(const GURL& url, 584 void WalletClient::MakeWalletRequest(const GURL& url,
660 const std::string& post_body) { 585 const std::string& post_body,
586 const std::string& mime_type) {
661 DCHECK(!HasRequestInProgress()); 587 DCHECK(!HasRequestInProgress());
662 588
663 request_.reset(net::URLFetcher::Create( 589 request_.reset(net::URLFetcher::Create(
664 0, url, net::URLFetcher::POST, this)); 590 0, url, net::URLFetcher::POST, this));
665 request_->SetRequestContext(context_getter_.get()); 591 request_->SetRequestContext(context_getter_.get());
666 VLOG(1) << "Making request to " << url << " with post_body=" << post_body; 592 VLOG(1) << "Making request to " << url << " with post_body=" << post_body;
667 request_->SetUploadData(kJsonMimeType, post_body); 593 request_->SetUploadData(mime_type, post_body);
668 request_->AddExtraRequestHeader("Authorization: GoogleLogin auth=" + 594 request_->AddExtraRequestHeader("Authorization: GoogleLogin auth=" +
669 delegate_->GetWalletCookieValue()); 595 delegate_->GetWalletCookieValue());
670 DVLOG(1) << "Setting authorization header value to " 596 DVLOG(1) << "Setting authorization header value to "
671 << delegate_->GetWalletCookieValue(); 597 << delegate_->GetWalletCookieValue();
672 request_started_timestamp_ = base::Time::Now(); 598 request_started_timestamp_ = base::Time::Now();
673 request_->Start(); 599 request_->Start();
674 600
675 delegate_->GetMetricLogger().LogWalletErrorMetric( 601 delegate_->GetMetricLogger().LogWalletErrorMetric(
676 delegate_->GetDialogType(), 602 delegate_->GetDialogType(),
677 AutofillMetrics::WALLET_ERROR_BASELINE_ISSUED_REQUEST); 603 AutofillMetrics::WALLET_ERROR_BASELINE_ISSUED_REQUEST);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 WalletItems::CreateWalletItems(*response_dict)); 712 WalletItems::CreateWalletItems(*response_dict));
787 if (wallet_items) { 713 if (wallet_items) {
788 LogRequiredActions(wallet_items->required_actions()); 714 LogRequiredActions(wallet_items->required_actions());
789 delegate_->OnDidGetWalletItems(wallet_items.Pass()); 715 delegate_->OnDidGetWalletItems(wallet_items.Pass());
790 } else { 716 } else {
791 HandleMalformedResponse(); 717 HandleMalformedResponse();
792 } 718 }
793 break; 719 break;
794 } 720 }
795 721
796 case SAVE_ADDRESS: { 722 case SAVE_TO_WALLET: {
797 std::string shipping_address_id;
798 std::vector<RequiredAction> required_actions;
799 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions);
800 std::vector<FormFieldError> form_errors;
801 GetFormFieldErrors(*response_dict, &form_errors);
802 if (response_dict->GetString(kShippingAddressIdKey,
803 &shipping_address_id) ||
804 !required_actions.empty()) {
805 LogRequiredActions(required_actions);
806 delegate_->OnDidSaveAddress(shipping_address_id,
807 required_actions,
808 form_errors);
809 } else {
810 HandleMalformedResponse();
811 }
812 break;
813 }
814
815 case SAVE_INSTRUMENT: {
816 std::string instrument_id;
817 std::vector<RequiredAction> required_actions;
818 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions);
819 std::vector<FormFieldError> form_errors;
820 GetFormFieldErrors(*response_dict, &form_errors);
821 if (response_dict->GetString(kInstrumentIdKey, &instrument_id) ||
822 !required_actions.empty()) {
823 LogRequiredActions(required_actions);
824 delegate_->OnDidSaveInstrument(instrument_id,
825 required_actions,
826 form_errors);
827 } else {
828 HandleMalformedResponse();
829 }
830 break;
831 }
832
833 case SAVE_INSTRUMENT_AND_ADDRESS: {
834 std::string instrument_id; 723 std::string instrument_id;
835 response_dict->GetString(kInstrumentIdKey, &instrument_id); 724 response_dict->GetString(kInstrumentIdKey, &instrument_id);
836 std::string shipping_address_id; 725 std::string shipping_address_id;
837 response_dict->GetString(kShippingAddressIdKey, 726 response_dict->GetString(kShippingAddressIdKey,
838 &shipping_address_id); 727 &shipping_address_id);
839 std::vector<RequiredAction> required_actions; 728 std::vector<RequiredAction> required_actions;
840 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions); 729 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions);
841 std::vector<FormFieldError> form_errors; 730 std::vector<FormFieldError> form_errors;
842 GetFormFieldErrors(*response_dict, &form_errors); 731 GetFormFieldErrors(*response_dict, &form_errors);
843 if ((!instrument_id.empty() && !shipping_address_id.empty()) || 732 if (instrument_id.empty() && shipping_address_id.empty() &&
844 !required_actions.empty()) { 733 required_actions.empty()) {
734 HandleMalformedResponse();
735 } else {
845 LogRequiredActions(required_actions); 736 LogRequiredActions(required_actions);
846 delegate_->OnDidSaveInstrumentAndAddress(instrument_id, 737 delegate_->OnDidSaveToWallet(instrument_id,
847 shipping_address_id, 738 shipping_address_id,
848 required_actions, 739 required_actions,
849 form_errors); 740 form_errors);
850 } else {
851 HandleMalformedResponse();
852 } 741 }
853 break; 742 break;
854 } 743 }
855
856 case UPDATE_ADDRESS: {
857 std::string address_id;
858 std::vector<RequiredAction> required_actions;
859 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions);
860 std::vector<FormFieldError> form_errors;
861 GetFormFieldErrors(*response_dict, &form_errors);
862 if (response_dict->GetString(kShippingAddressIdKey, &address_id) ||
863 !required_actions.empty()) {
864 LogRequiredActions(required_actions);
865 delegate_->OnDidUpdateAddress(address_id,
866 required_actions,
867 form_errors);
868 } else {
869 HandleMalformedResponse();
870 }
871 break;
872 }
873
874 case UPDATE_INSTRUMENT: {
875 std::string instrument_id;
876 std::vector<RequiredAction> required_actions;
877 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions);
878 std::vector<FormFieldError> form_errors;
879 GetFormFieldErrors(*response_dict, &form_errors);
880 if (response_dict->GetString(kInstrumentIdKey, &instrument_id) ||
881 !required_actions.empty()) {
882 LogRequiredActions(required_actions);
883 delegate_->OnDidUpdateInstrument(instrument_id,
884 required_actions,
885 form_errors);
886 } else {
887 HandleMalformedResponse();
888 }
889 break;
890 }
891 744
892 case NO_PENDING_REQUEST: 745 case NO_PENDING_REQUEST:
893 NOTREACHED(); 746 NOTREACHED();
894 } 747 }
895 748
896 request_.reset(); 749 request_.reset();
897 StartNextPendingRequest(); 750 StartNextPendingRequest();
898 } 751 }
899 752
900 void WalletClient::StartNextPendingRequest() { 753 void WalletClient::StartNextPendingRequest() {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 break; 797 break;
945 } 798 }
946 799
947 VLOG(1) << "Wallet encountered a " << error_message; 800 VLOG(1) << "Wallet encountered a " << error_message;
948 801
949 delegate_->OnWalletError(error_type); 802 delegate_->OnWalletError(error_type);
950 delegate_->GetMetricLogger().LogWalletErrorMetric( 803 delegate_->GetMetricLogger().LogWalletErrorMetric(
951 delegate_->GetDialogType(), ErrorTypeToUmaMetric(error_type)); 804 delegate_->GetDialogType(), ErrorTypeToUmaMetric(error_type));
952 } 805 }
953 806
954 void WalletClient::OnDidEncryptOneTimePad(
955 const std::string& encrypted_one_time_pad,
956 const std::string& session_material) {
957 DCHECK_EQ(GET_FULL_WALLET, request_type_);
958 pending_request_body_.SetString(kEncryptedOtpKey, encrypted_one_time_pad);
959 pending_request_body_.SetString(kSessionMaterialKey, session_material);
960
961 std::string post_body;
962 base::JSONWriter::Write(&pending_request_body_, &post_body);
963 pending_request_body_.Clear();
964
965 MakeWalletRequest(GetGetFullWalletUrl(), post_body);
966 }
967
968 void WalletClient::OnDidEscrowInstrumentInformation(
969 const std::string& escrow_handle) {
970 DCHECK(request_type_ == SAVE_INSTRUMENT ||
971 request_type_ == SAVE_INSTRUMENT_AND_ADDRESS);
972
973 pending_request_body_.SetString(kInstrumentEscrowHandleKey, escrow_handle);
974
975 std::string post_body;
976 base::JSONWriter::Write(&pending_request_body_, &post_body);
977 pending_request_body_.Clear();
978
979 MakeWalletRequest(GetSaveToWalletUrl(), post_body);
980 }
981
982 void WalletClient::OnDidEscrowCardVerificationNumber(
983 const std::string& escrow_handle) {
984 DCHECK(request_type_ == AUTHENTICATE_INSTRUMENT ||
985 request_type_ == UPDATE_INSTRUMENT);
986 pending_request_body_.SetString(kInstrumentEscrowHandleKey, escrow_handle);
987
988 std::string post_body;
989 base::JSONWriter::Write(&pending_request_body_, &post_body);
990 pending_request_body_.Clear();
991
992 if (request_type_ == AUTHENTICATE_INSTRUMENT)
993 MakeWalletRequest(GetAuthenticateInstrumentUrl(), post_body);
994 else
995 MakeWalletRequest(GetSaveToWalletUrl(), post_body);
996 }
997
998 void WalletClient::OnDidMakeRequest() {
999 delegate_->GetMetricLogger().LogWalletErrorMetric(
1000 delegate_->GetDialogType(),
1001 AutofillMetrics::WALLET_ERROR_BASELINE_ISSUED_REQUEST);
1002 }
1003
1004 void WalletClient::OnNetworkError() {
1005 HandleWalletError(NETWORK_ERROR);
1006 }
1007
1008 void WalletClient::OnMalformedResponse() {
1009 HandleWalletError(MALFORMED_RESPONSE);
1010 }
1011
1012 // Logs an UMA metric for each of the |required_actions|. 807 // Logs an UMA metric for each of the |required_actions|.
1013 void WalletClient::LogRequiredActions( 808 void WalletClient::LogRequiredActions(
1014 const std::vector<RequiredAction>& required_actions) const { 809 const std::vector<RequiredAction>& required_actions) const {
1015 for (size_t i = 0; i < required_actions.size(); ++i) { 810 for (size_t i = 0; i < required_actions.size(); ++i) {
1016 delegate_->GetMetricLogger().LogWalletRequiredActionMetric( 811 delegate_->GetMetricLogger().LogWalletRequiredActionMetric(
1017 delegate_->GetDialogType(), 812 delegate_->GetDialogType(),
1018 RequiredActionToUmaMetric(required_actions[i])); 813 RequiredActionToUmaMetric(required_actions[i]));
1019 } 814 }
1020 } 815 }
1021 816
1022 AutofillMetrics::WalletApiCallMetric WalletClient::RequestTypeToUmaMetric( 817 AutofillMetrics::WalletApiCallMetric WalletClient::RequestTypeToUmaMetric(
1023 RequestType request_type) const { 818 RequestType request_type) const {
1024 switch (request_type) { 819 switch (request_type) {
1025 case ACCEPT_LEGAL_DOCUMENTS: 820 case ACCEPT_LEGAL_DOCUMENTS:
1026 return AutofillMetrics::ACCEPT_LEGAL_DOCUMENTS; 821 return AutofillMetrics::ACCEPT_LEGAL_DOCUMENTS;
1027 case AUTHENTICATE_INSTRUMENT: 822 case AUTHENTICATE_INSTRUMENT:
1028 return AutofillMetrics::AUTHENTICATE_INSTRUMENT; 823 return AutofillMetrics::AUTHENTICATE_INSTRUMENT;
1029 case GET_FULL_WALLET: 824 case GET_FULL_WALLET:
1030 return AutofillMetrics::GET_FULL_WALLET; 825 return AutofillMetrics::GET_FULL_WALLET;
1031 case GET_WALLET_ITEMS: 826 case GET_WALLET_ITEMS:
1032 return AutofillMetrics::GET_WALLET_ITEMS; 827 return AutofillMetrics::GET_WALLET_ITEMS;
1033 case SAVE_ADDRESS: 828 case SAVE_TO_WALLET:
1034 return AutofillMetrics::SAVE_ADDRESS; 829 return AutofillMetrics::SAVE_TO_WALLET;
1035 case SAVE_INSTRUMENT:
1036 return AutofillMetrics::SAVE_INSTRUMENT;
1037 case SAVE_INSTRUMENT_AND_ADDRESS:
1038 return AutofillMetrics::SAVE_INSTRUMENT_AND_ADDRESS;
1039 case SEND_STATUS: 830 case SEND_STATUS:
1040 return AutofillMetrics::SEND_STATUS; 831 return AutofillMetrics::SEND_STATUS;
1041 case UPDATE_ADDRESS:
1042 return AutofillMetrics::UPDATE_ADDRESS;
1043 case UPDATE_INSTRUMENT:
1044 return AutofillMetrics::UPDATE_INSTRUMENT;
1045 case NO_PENDING_REQUEST: 832 case NO_PENDING_REQUEST:
1046 NOTREACHED(); 833 NOTREACHED();
1047 return AutofillMetrics::UNKNOWN_API_CALL; 834 return AutofillMetrics::UNKNOWN_API_CALL;
1048 } 835 }
1049 836
1050 NOTREACHED(); 837 NOTREACHED();
1051 return AutofillMetrics::UNKNOWN_API_CALL; 838 return AutofillMetrics::UNKNOWN_API_CALL;
1052 } 839 }
1053 840
1054 } // namespace wallet 841 } // namespace wallet
1055 } // namespace autofill 842 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698