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

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: No !! 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 namespace autofill { 30 namespace autofill {
27 namespace wallet { 31 namespace wallet {
28 32
29 namespace { 33 namespace {
30 34
35 const char kFormEncodedMimeType[] = "application/x-www-form-urlencoded";
31 const char kJsonMimeType[] = "application/json"; 36 const char kJsonMimeType[] = "application/json";
37 const char kEscrowSensitiveInformationFormat[] =
38 "request_content_type=application/json&request=%s&cvn=%s&card_number=%s";
39 const char kGetFullWalletRequestFormat[] =
40 "request_content_type=application/json&request=%s&otp=%s:%s";
32 const size_t kOneTimePadLength = 6; 41 const size_t kOneTimePadLength = 6;
33 42
43 // The maximum number of bits in the one time pad that the server is willing to
44 // accept.
45 const size_t kMaxBits = 56;
46
47 // The minimum number of bits in the one time pad that the server is willing to
48 // accept.
49 const size_t kMinBits = 40;
50
34 std::string AutocheckoutStatusToString(AutocheckoutStatus status) { 51 std::string AutocheckoutStatusToString(AutocheckoutStatus status) {
35 switch (status) { 52 switch (status) {
36 case MISSING_FIELDMAPPING: 53 case MISSING_FIELDMAPPING:
37 return "MISSING_FIELDMAPPING"; 54 return "MISSING_FIELDMAPPING";
38 case MISSING_ADVANCE: 55 case MISSING_ADVANCE:
39 return "MISSING_ADVANCE"; 56 return "MISSING_ADVANCE";
40 case MISSING_CLICK_ELEMENT_BEFORE_FORM_FILLING: 57 case MISSING_CLICK_ELEMENT_BEFORE_FORM_FILLING:
41 return "MISSING_CLICK_ELEMENT_BEFORE_FORM_FILLING"; 58 return "MISSING_CLICK_ELEMENT_BEFORE_FORM_FILLING";
42 case MISSING_CLICK_ELEMENT_AFTER_FORM_FILLING: 59 case MISSING_CLICK_ELEMENT_AFTER_FORM_FILLING:
43 return "MISSING_CLICK_ELEMENT_AFTER_FORM_FILLING"; 60 return "MISSING_CLICK_ELEMENT_AFTER_FORM_FILLING";
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 const std::string& google_transaction_id, 250 const std::string& google_transaction_id,
234 const std::vector<RiskCapability> risk_capabilities) 251 const std::vector<RiskCapability> risk_capabilities)
235 : instrument_id(instrument_id), 252 : instrument_id(instrument_id),
236 address_id(address_id), 253 address_id(address_id),
237 source_url(source_url), 254 source_url(source_url),
238 google_transaction_id(google_transaction_id), 255 google_transaction_id(google_transaction_id),
239 risk_capabilities(risk_capabilities) {} 256 risk_capabilities(risk_capabilities) {}
240 257
241 WalletClient::FullWalletRequest::~FullWalletRequest() {} 258 WalletClient::FullWalletRequest::~FullWalletRequest() {}
242 259
243 WalletClient::UpdateInstrumentRequest::UpdateInstrumentRequest(
244 const std::string& instrument_id,
245 const GURL& source_url)
246 : instrument_id(instrument_id),
247 expiration_month(0),
248 expiration_year(0),
249 source_url(source_url) {}
250
251 WalletClient::UpdateInstrumentRequest::~UpdateInstrumentRequest() {}
252
253 WalletClient::WalletClient(net::URLRequestContextGetter* context_getter, 260 WalletClient::WalletClient(net::URLRequestContextGetter* context_getter,
254 WalletClientDelegate* delegate) 261 WalletClientDelegate* delegate)
255 : context_getter_(context_getter), 262 : context_getter_(context_getter),
256 delegate_(delegate), 263 delegate_(delegate),
257 request_type_(NO_PENDING_REQUEST), 264 request_type_(NO_PENDING_REQUEST),
258 one_time_pad_(kOneTimePadLength), 265 one_time_pad_(kOneTimePadLength) {
259 encryption_escrow_client_(context_getter, this) {
260 DCHECK(context_getter_.get()); 266 DCHECK(context_getter_.get());
261 DCHECK(delegate_); 267 DCHECK(delegate_);
262 } 268 }
263 269
264 WalletClient::~WalletClient() {} 270 WalletClient::~WalletClient() {}
265 271
266 void WalletClient::AcceptLegalDocuments( 272 void WalletClient::AcceptLegalDocuments(
267 const std::vector<WalletItems::LegalDocument*>& documents, 273 const std::vector<WalletItems::LegalDocument*>& documents,
268 const std::string& google_transaction_id, 274 const std::string& google_transaction_id,
269 const GURL& source_url) { 275 const GURL& source_url) {
270 if (documents.empty()) 276 if (documents.empty())
271 return; 277 return;
272 278
273 std::vector<std::string> document_ids; 279 std::vector<std::string> document_ids;
274 for (size_t i = 0; i < documents.size(); ++i) { 280 for (size_t i = 0; i < documents.size(); ++i) {
275 document_ids.push_back(documents[i]->id()); 281 document_ids.push_back(documents[i]->id());
276 } 282 }
277 DoAcceptLegalDocuments(document_ids, google_transaction_id, source_url); 283 DoAcceptLegalDocuments(document_ids, google_transaction_id, source_url);
278 } 284 }
279 285
280 void WalletClient::AuthenticateInstrument( 286 void WalletClient::AuthenticateInstrument(
281 const std::string& instrument_id, 287 const std::string& instrument_id,
282 const std::string& card_verification_number, 288 const std::string& card_verification_number) {
283 const std::string& obfuscated_gaia_id) {
284 if (HasRequestInProgress()) { 289 if (HasRequestInProgress()) {
285 pending_requests_.push(base::Bind(&WalletClient::AuthenticateInstrument, 290 pending_requests_.push(base::Bind(&WalletClient::AuthenticateInstrument,
286 base::Unretained(this), 291 base::Unretained(this),
287 instrument_id, 292 instrument_id,
288 card_verification_number, 293 card_verification_number));
289 obfuscated_gaia_id));
290 return; 294 return;
291 } 295 }
292 296
293 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); 297 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
294 DCHECK(pending_request_body_.empty());
295 request_type_ = AUTHENTICATE_INSTRUMENT; 298 request_type_ = AUTHENTICATE_INSTRUMENT;
296 299
297 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); 300 base::DictionaryValue request_dict;
298 pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData()); 301 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
299 pending_request_body_.SetString(kInstrumentIdKey, instrument_id); 302 request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData());
303 request_dict.SetString(kInstrumentIdKey, instrument_id);
300 304
301 encryption_escrow_client_.EscrowCardVerificationNumber( 305 std::string json_payload;
302 card_verification_number, obfuscated_gaia_id); 306 base::JSONWriter::Write(&request_dict, &json_payload);
307
308 std::string escaped_card_verification_number = net::EscapeUrlEncodedData(
309 card_verification_number, true);
310
311 std::string post_body = base::StringPrintf(
312 kEscrowSensitiveInformationFormat,
313 net::EscapeUrlEncodedData(json_payload, true).c_str(),
314 escaped_card_verification_number.c_str(),
315 std::string().c_str());
316
317 MakeWalletRequest(GetAuthenticateInstrumentUrl(),
318 post_body,
319 kFormEncodedMimeType);
303 } 320 }
304 321
305 void WalletClient::GetFullWallet(const FullWalletRequest& full_wallet_request) { 322 void WalletClient::GetFullWallet(const FullWalletRequest& full_wallet_request) {
306 if (HasRequestInProgress()) { 323 if (HasRequestInProgress()) {
307 pending_requests_.push(base::Bind(&WalletClient::GetFullWallet, 324 pending_requests_.push(base::Bind(&WalletClient::GetFullWallet,
308 base::Unretained(this), 325 base::Unretained(this),
309 full_wallet_request)); 326 full_wallet_request));
310 return; 327 return;
311 } 328 }
312 329
313 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); 330 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
314 DCHECK(pending_request_body_.empty());
315 request_type_ = GET_FULL_WALLET; 331 request_type_ = GET_FULL_WALLET;
316 332
317 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); 333 base::DictionaryValue request_dict;
318 pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData()); 334 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
319 pending_request_body_.SetString(kSelectedInstrumentIdKey, 335 request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData());
320 full_wallet_request.instrument_id); 336 request_dict.SetString(kSelectedInstrumentIdKey,
321 pending_request_body_.SetString(kSelectedAddressIdKey, 337 full_wallet_request.instrument_id);
322 full_wallet_request.address_id); 338 request_dict.SetString(kSelectedAddressIdKey, full_wallet_request.address_id);
323 pending_request_body_.SetString( 339 request_dict.SetString(
324 kMerchantDomainKey, 340 kMerchantDomainKey,
325 full_wallet_request.source_url.GetWithEmptyPath().spec()); 341 full_wallet_request.source_url.GetWithEmptyPath().spec());
326 pending_request_body_.SetString(kGoogleTransactionIdKey, 342 request_dict.SetString(kGoogleTransactionIdKey,
327 full_wallet_request.google_transaction_id); 343 full_wallet_request.google_transaction_id);
328 pending_request_body_.SetString( 344 request_dict.SetString(kFeatureKey,
329 kFeatureKey, 345 DialogTypeToFeatureString(delegate_->GetDialogType()));
330 DialogTypeToFeatureString(delegate_->GetDialogType()));
331 346
332 scoped_ptr<base::ListValue> risk_capabilities_list(new base::ListValue()); 347 scoped_ptr<base::ListValue> risk_capabilities_list(new base::ListValue());
333 for (std::vector<RiskCapability>::const_iterator it = 348 for (std::vector<RiskCapability>::const_iterator it =
334 full_wallet_request.risk_capabilities.begin(); 349 full_wallet_request.risk_capabilities.begin();
335 it != full_wallet_request.risk_capabilities.end(); 350 it != full_wallet_request.risk_capabilities.end();
336 ++it) { 351 ++it) {
337 risk_capabilities_list->AppendString(RiskCapabilityToString(*it)); 352 risk_capabilities_list->AppendString(RiskCapabilityToString(*it));
338 } 353 }
339 pending_request_body_.Set(kRiskCapabilitiesKey, 354 request_dict.Set(kRiskCapabilitiesKey, risk_capabilities_list.release());
340 risk_capabilities_list.release()); 355
356 std::string json_payload;
357 base::JSONWriter::Write(&request_dict, &json_payload);
341 358
342 crypto::RandBytes(&(one_time_pad_[0]), one_time_pad_.size()); 359 crypto::RandBytes(&(one_time_pad_[0]), one_time_pad_.size());
343 encryption_escrow_client_.EncryptOneTimePad(one_time_pad_); 360
361 size_t num_bits = one_time_pad_.size() * 8;
362 DCHECK_LE(num_bits, kMaxBits);
363 DCHECK_GE(num_bits, kMinBits);
364
365 std::string post_body = base::StringPrintf(
366 kGetFullWalletRequestFormat,
367 net::EscapeUrlEncodedData(json_payload, true).c_str(),
368 base::HexEncode(&num_bits, 1).c_str(),
369 base::HexEncode(&(one_time_pad_[0]), one_time_pad_.size()).c_str());
370
371 MakeWalletRequest(GetGetFullWalletUrl(), post_body, kFormEncodedMimeType);
344 } 372 }
345 373
346 void WalletClient::GetWalletItems(const GURL& source_url) { 374 void WalletClient::SaveToWallet(scoped_ptr<Instrument> instrument,
375 scoped_ptr<Address> address,
376 const GURL& source_url) {
377 DCHECK(instrument || address);
347 if (HasRequestInProgress()) { 378 if (HasRequestInProgress()) {
348 pending_requests_.push(base::Bind(&WalletClient::GetWalletItems, 379 pending_requests_.push(base::Bind(&WalletClient::SaveToWallet,
349 base::Unretained(this), 380 base::Unretained(this),
381 base::Passed(&instrument),
382 base::Passed(&address),
350 source_url)); 383 source_url));
351 return; 384 return;
352 } 385 }
353 386
354 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); 387 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
355 request_type_ = GET_WALLET_ITEMS; 388 request_type_ = SAVE_TO_WALLET;
Dan Beam 2013/07/02 21:03:11 this could maybe be made into a helper function
ahutter 2013/07/02 21:15:56 Like a SetRequestType function? or am I missing so
Dan Beam 2013/07/02 21:17:46 yes
356 389
357 base::DictionaryValue request_dict; 390 base::DictionaryValue request_dict;
358 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey()); 391 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
359 request_dict.SetString(kMerchantDomainKey,
360 source_url.GetWithEmptyPath().spec());
361
362 std::string post_body;
363 base::JSONWriter::Write(&request_dict, &post_body);
364
365 MakeWalletRequest(GetGetWalletItemsUrl(), post_body);
366 }
367
368 void WalletClient::SaveAddress(const Address& shipping_address,
369 const GURL& source_url) {
370 if (HasRequestInProgress()) {
371 pending_requests_.push(base::Bind(&WalletClient::SaveAddress,
372 base::Unretained(this),
373 shipping_address,
374 source_url));
375 return;
376 }
377
378 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
379 request_type_ = SAVE_ADDRESS;
380
381 base::DictionaryValue request_dict;
382 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
383 request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData()); 392 request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData());
384 request_dict.SetString(kMerchantDomainKey, 393 request_dict.SetString(kMerchantDomainKey,
385 source_url.GetWithEmptyPath().spec()); 394 source_url.GetWithEmptyPath().spec());
386 395
387 request_dict.Set(kShippingAddressKey, 396 std::string primary_account_number;
388 shipping_address.ToDictionaryWithID().release()); 397 std::string card_verification_number;
398 if (instrument) {
399 primary_account_number = net::EscapeUrlEncodedData(
400 UTF16ToUTF8(instrument->primary_account_number()), true);
401 card_verification_number = net::EscapeUrlEncodedData(
402 UTF16ToUTF8(instrument->card_verification_number()), true);
Dan Beam 2013/07/02 21:03:11 nit: \n
ahutter 2013/07/02 21:15:56 Done.
403 if (instrument->object_id().empty()) {
404 request_dict.Set(kInstrumentKey, instrument->ToDictionary().release());
405 request_dict.SetString(kInstrumentPhoneNumberKey,
406 instrument->address()->phone_number());
407 } else {
408 DCHECK(instrument->address() ||
409 (instrument->expiration_month() > 0 &&
410 instrument->expiration_year() > 0));
389 411
390 std::string post_body; 412 request_dict.SetString(kUpgradedInstrumentIdKey,
391 base::JSONWriter::Write(&request_dict, &post_body); 413 instrument->object_id());
392 414
393 MakeWalletRequest(GetSaveToWalletUrl(), post_body); 415 if (instrument->address()) {
416 request_dict.SetString(kInstrumentPhoneNumberKey,
417 instrument->address()->phone_number());
418 request_dict.Set(
419 kUpgradedBillingAddressKey,
420 instrument->address()->ToDictionaryWithoutID().release());
421 }
422
423 if (instrument->expiration_month() > 0 &&
424 instrument->expiration_year() > 0) {
425 DCHECK(!instrument->card_verification_number().empty());
426 request_dict.SetInteger(kInstrumentExpMonthKey,
427 instrument->expiration_month());
428 request_dict.SetInteger(kInstrumentExpYearKey,
429 instrument->expiration_year());
430 }
431
432 if (request_dict.HasKey(kInstrumentKey))
433 request_dict.SetString(kInstrumentType, "CREDIT_CARD");
434 }
435 }
436 if (address) {
437 request_dict.Set(kShippingAddressKey,
438 address->ToDictionaryWithID().release());
439 }
440
Dan Beam 2013/07/02 21:03:11 ^H
ahutter 2013/07/02 21:15:56 Done.
441
442 std::string json_payload;
443 base::JSONWriter::Write(&request_dict, &json_payload);
444
445 std::string post_body = base::StringPrintf(
446 kEscrowSensitiveInformationFormat,
447 net::EscapeUrlEncodedData(json_payload, true).c_str(),
448 card_verification_number.c_str(),
449 primary_account_number.c_str());
450
451 MakeWalletRequest(GetSaveToWalletUrl(), post_body, kFormEncodedMimeType);
394 } 452 }
395 453
396 void WalletClient::SaveInstrument( 454 void WalletClient::GetWalletItems(const GURL& source_url) {
397 const Instrument& instrument,
398 const std::string& obfuscated_gaia_id,
399 const GURL& source_url) {
400 if (HasRequestInProgress()) { 455 if (HasRequestInProgress()) {
401 pending_requests_.push(base::Bind(&WalletClient::SaveInstrument, 456 pending_requests_.push(base::Bind(&WalletClient::GetWalletItems,
402 base::Unretained(this), 457 base::Unretained(this),
403 instrument,
404 obfuscated_gaia_id,
405 source_url)); 458 source_url));
406 return; 459 return;
407 } 460 }
408 461
409 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); 462 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
410 DCHECK(pending_request_body_.empty()); 463 request_type_ = GET_WALLET_ITEMS;
411 request_type_ = SAVE_INSTRUMENT;
412 464
413 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); 465 base::DictionaryValue request_dict;
414 pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData()); 466 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
415 pending_request_body_.SetString(kMerchantDomainKey, 467 request_dict.SetString(kMerchantDomainKey,
416 source_url.GetWithEmptyPath().spec()); 468 source_url.GetWithEmptyPath().spec());
417 469
418 pending_request_body_.Set(kInstrumentKey, 470 std::string post_body;
419 instrument.ToDictionary().release()); 471 base::JSONWriter::Write(&request_dict, &post_body);
420 pending_request_body_.SetString(kInstrumentPhoneNumberKey,
421 instrument.address().phone_number());
422 472
423 encryption_escrow_client_.EscrowInstrumentInformation(instrument, 473 MakeWalletRequest(GetGetWalletItemsUrl(), post_body, kJsonMimeType);
424 obfuscated_gaia_id);
425 }
426
427 void WalletClient::SaveInstrumentAndAddress(
428 const Instrument& instrument,
429 const Address& address,
430 const std::string& obfuscated_gaia_id,
431 const GURL& source_url) {
432 if (HasRequestInProgress()) {
433 pending_requests_.push(base::Bind(&WalletClient::SaveInstrumentAndAddress,
434 base::Unretained(this),
435 instrument,
436 address,
437 obfuscated_gaia_id,
438 source_url));
439 return;
440 }
441
442 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
443 DCHECK(pending_request_body_.empty());
444 request_type_ = SAVE_INSTRUMENT_AND_ADDRESS;
445
446 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey());
447 pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData());
448 pending_request_body_.SetString(kMerchantDomainKey,
449 source_url.GetWithEmptyPath().spec());
450
451 pending_request_body_.Set(kInstrumentKey,
452 instrument.ToDictionary().release());
453 pending_request_body_.SetString(kInstrumentPhoneNumberKey,
454 instrument.address().phone_number());
455
456 pending_request_body_.Set(kShippingAddressKey,
457 address.ToDictionaryWithID().release());
458
459 encryption_escrow_client_.EscrowInstrumentInformation(instrument,
460 obfuscated_gaia_id);
461 } 474 }
462 475
463 void WalletClient::SendAutocheckoutStatus( 476 void WalletClient::SendAutocheckoutStatus(
464 AutocheckoutStatus status, 477 AutocheckoutStatus status,
465 const GURL& source_url, 478 const GURL& source_url,
466 const std::vector<AutocheckoutStatistic>& latency_statistics, 479 const std::vector<AutocheckoutStatistic>& latency_statistics,
467 const std::string& google_transaction_id) { 480 const std::string& google_transaction_id) {
468 DVLOG(1) << "Sending Autocheckout Status: " << status 481 DVLOG(1) << "Sending Autocheckout Status: " << status
469 << " for: " << source_url; 482 << " for: " << source_url;
470 if (HasRequestInProgress()) { 483 if (HasRequestInProgress()) {
(...skipping 25 matching lines...) Expand all
496 latency_statistics[i].ToDictionary().release()); 509 latency_statistics[i].ToDictionary().release());
497 } 510 }
498 request_dict.Set(kAutocheckoutStepsKey, 511 request_dict.Set(kAutocheckoutStepsKey,
499 latency_statistics_json.release()); 512 latency_statistics_json.release());
500 } 513 }
501 request_dict.SetString(kGoogleTransactionIdKey, google_transaction_id); 514 request_dict.SetString(kGoogleTransactionIdKey, google_transaction_id);
502 515
503 std::string post_body; 516 std::string post_body;
504 base::JSONWriter::Write(&request_dict, &post_body); 517 base::JSONWriter::Write(&request_dict, &post_body);
505 518
506 MakeWalletRequest(GetSendStatusUrl(), post_body); 519 MakeWalletRequest(GetSendStatusUrl(), post_body, kJsonMimeType);
507 }
508
509 void WalletClient::UpdateAddress(const Address& address,
510 const GURL& source_url) {
511 if (HasRequestInProgress()) {
512 pending_requests_.push(base::Bind(&WalletClient::UpdateAddress,
513 base::Unretained(this),
514 address,
515 source_url));
516 return;
517 }
518
519 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
520 request_type_ = UPDATE_ADDRESS;
521
522 base::DictionaryValue request_dict;
523 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
524 request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData());
525 request_dict.SetString(kMerchantDomainKey,
526 source_url.GetWithEmptyPath().spec());
527
528 request_dict.Set(kShippingAddressKey,
529 address.ToDictionaryWithID().release());
530
531 std::string post_body;
532 base::JSONWriter::Write(&request_dict, &post_body);
533
534 MakeWalletRequest(GetSaveToWalletUrl(), post_body);
535 }
536
537 void WalletClient::UpdateInstrument(
538 const UpdateInstrumentRequest& update_instrument_request,
539 scoped_ptr<Address> billing_address) {
540 if (HasRequestInProgress()) {
541 pending_requests_.push(base::Bind(&WalletClient::UpdateInstrument,
542 base::Unretained(this),
543 update_instrument_request,
544 base::Passed(&billing_address)));
545 return;
546 }
547
548 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
549 DCHECK(pending_request_body_.empty());
550 DCHECK(update_instrument_request.card_verification_number.empty() ==
551 update_instrument_request.obfuscated_gaia_id.empty());
552 DCHECK(billing_address ||
553 (update_instrument_request.expiration_month > 0 &&
554 update_instrument_request.expiration_year > 0));
555
556 request_type_ = UPDATE_INSTRUMENT;
557
558 base::DictionaryValue* active_request_body;
559 base::DictionaryValue request_dict;
560 if (update_instrument_request.card_verification_number.empty())
561 active_request_body = &request_dict;
562 else
563 active_request_body = &pending_request_body_;
564
565 active_request_body->SetString(kApiKeyKey, google_apis::GetAPIKey());
566 active_request_body->SetString(kRiskParamsKey, delegate_->GetRiskData());
567 active_request_body->SetString(
568 kMerchantDomainKey,
569 update_instrument_request.source_url.GetWithEmptyPath().spec());
570
571 active_request_body->SetString(kUpgradedInstrumentIdKey,
572 update_instrument_request.instrument_id);
573
574 if (billing_address) {
575 active_request_body->SetString(kInstrumentPhoneNumberKey,
576 billing_address->phone_number());
577 active_request_body->Set(
578 kUpgradedBillingAddressKey,
579 billing_address->ToDictionaryWithoutID().release());
580 }
581
582 if (update_instrument_request.expiration_month > 0 &&
583 update_instrument_request.expiration_year > 0) {
584 DCHECK(!update_instrument_request.card_verification_number.empty());
585 active_request_body->SetInteger(
586 kInstrumentExpMonthKey,
587 update_instrument_request.expiration_month);
588 active_request_body->SetInteger(kInstrumentExpYearKey,
589 update_instrument_request.expiration_year);
590 }
591
592 if (active_request_body->HasKey(kInstrumentKey))
593 active_request_body->SetString(kInstrumentType, "CREDIT_CARD");
594
595 if (update_instrument_request.card_verification_number.empty()) {
596 std::string post_body;
597 base::JSONWriter::Write(active_request_body, &post_body);
598 MakeWalletRequest(GetSaveToWalletUrl(), post_body);
599 } else {
600 encryption_escrow_client_.EscrowCardVerificationNumber(
601 update_instrument_request.card_verification_number,
602 update_instrument_request.obfuscated_gaia_id);
603 }
604 } 520 }
605 521
606 bool WalletClient::HasRequestInProgress() const { 522 bool WalletClient::HasRequestInProgress() const {
607 // |SaveInstrument*()| and |UpdateInstrument()| methods don't set |request_| 523 return request_;
608 // until sensitive info has been escrowed, so this class is considered to have
609 // a request in progress if |encryption_escrow_client_| is working as well.
610 return request_ || encryption_escrow_client_.HasRequestInProgress();
611 } 524 }
612 525
613 void WalletClient::CancelRequests() { 526 void WalletClient::CancelRequests() {
614 encryption_escrow_client_.CancelRequest();
615 pending_request_body_.Clear();
616 request_.reset(); 527 request_.reset();
617 request_type_ = NO_PENDING_REQUEST; 528 request_type_ = NO_PENDING_REQUEST;
618 while (!pending_requests_.empty()) { 529 while (!pending_requests_.empty()) {
619 pending_requests_.pop(); 530 pending_requests_.pop();
620 } 531 }
621 } 532 }
622 533
623 void WalletClient::DoAcceptLegalDocuments( 534 void WalletClient::DoAcceptLegalDocuments(
624 const std::vector<std::string>& document_ids, 535 const std::vector<std::string>& document_ids,
625 const std::string& google_transaction_id, 536 const std::string& google_transaction_id,
(...skipping 19 matching lines...) Expand all
645 for (std::vector<std::string>::const_iterator it = document_ids.begin(); 556 for (std::vector<std::string>::const_iterator it = document_ids.begin();
646 it != document_ids.end(); ++it) { 557 it != document_ids.end(); ++it) {
647 if (!it->empty()) 558 if (!it->empty())
648 docs_list->AppendString(*it); 559 docs_list->AppendString(*it);
649 } 560 }
650 request_dict.Set(kAcceptedLegalDocumentKey, docs_list.release()); 561 request_dict.Set(kAcceptedLegalDocumentKey, docs_list.release());
651 562
652 std::string post_body; 563 std::string post_body;
653 base::JSONWriter::Write(&request_dict, &post_body); 564 base::JSONWriter::Write(&request_dict, &post_body);
654 565
655 MakeWalletRequest(GetAcceptLegalDocumentsUrl(), post_body); 566 MakeWalletRequest(GetAcceptLegalDocumentsUrl(), post_body, kJsonMimeType);
656 } 567 }
657 568
658 void WalletClient::MakeWalletRequest(const GURL& url, 569 void WalletClient::MakeWalletRequest(const GURL& url,
659 const std::string& post_body) { 570 const std::string& post_body,
571 const std::string& mime_type) {
660 DCHECK(!HasRequestInProgress()); 572 DCHECK(!HasRequestInProgress());
661 573
662 request_.reset(net::URLFetcher::Create( 574 request_.reset(net::URLFetcher::Create(
663 0, url, net::URLFetcher::POST, this)); 575 0, url, net::URLFetcher::POST, this));
664 request_->SetRequestContext(context_getter_.get()); 576 request_->SetRequestContext(context_getter_.get());
665 DVLOG(1) << "Making request to " << url << " with post_body=" << post_body; 577 DVLOG(1) << "Making request to " << url << " with post_body=" << post_body;
666 request_->SetUploadData(kJsonMimeType, post_body); 578 request_->SetUploadData(mime_type, post_body);
667 request_started_timestamp_ = base::Time::Now(); 579 request_started_timestamp_ = base::Time::Now();
668 request_->Start(); 580 request_->Start();
669 581
670 delegate_->GetMetricLogger().LogWalletErrorMetric( 582 delegate_->GetMetricLogger().LogWalletErrorMetric(
671 delegate_->GetDialogType(), 583 delegate_->GetDialogType(),
672 AutofillMetrics::WALLET_ERROR_BASELINE_ISSUED_REQUEST); 584 AutofillMetrics::WALLET_ERROR_BASELINE_ISSUED_REQUEST);
673 delegate_->GetMetricLogger().LogWalletRequiredActionMetric( 585 delegate_->GetMetricLogger().LogWalletRequiredActionMetric(
674 delegate_->GetDialogType(), 586 delegate_->GetDialogType(),
675 AutofillMetrics::WALLET_REQUIRED_ACTION_BASELINE_ISSUED_REQUEST); 587 AutofillMetrics::WALLET_REQUIRED_ACTION_BASELINE_ISSUED_REQUEST);
676 } 588 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 WalletItems::CreateWalletItems(*response_dict)); 693 WalletItems::CreateWalletItems(*response_dict));
782 if (wallet_items) { 694 if (wallet_items) {
783 LogRequiredActions(wallet_items->required_actions()); 695 LogRequiredActions(wallet_items->required_actions());
784 delegate_->OnDidGetWalletItems(wallet_items.Pass()); 696 delegate_->OnDidGetWalletItems(wallet_items.Pass());
785 } else { 697 } else {
786 HandleMalformedResponse(); 698 HandleMalformedResponse();
787 } 699 }
788 break; 700 break;
789 } 701 }
790 702
791 case SAVE_ADDRESS: { 703 case SAVE_TO_WALLET: {
792 std::string shipping_address_id;
793 std::vector<RequiredAction> required_actions;
794 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions);
795 std::vector<FormFieldError> form_errors;
796 GetFormFieldErrors(*response_dict, &form_errors);
797 if (response_dict->GetString(kShippingAddressIdKey,
798 &shipping_address_id) ||
799 !required_actions.empty()) {
800 LogRequiredActions(required_actions);
801 delegate_->OnDidSaveAddress(shipping_address_id,
802 required_actions,
803 form_errors);
804 } else {
805 HandleMalformedResponse();
806 }
807 break;
808 }
809
810 case SAVE_INSTRUMENT: {
811 std::string instrument_id;
812 std::vector<RequiredAction> required_actions;
813 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions);
814 std::vector<FormFieldError> form_errors;
815 GetFormFieldErrors(*response_dict, &form_errors);
816 if (response_dict->GetString(kInstrumentIdKey, &instrument_id) ||
817 !required_actions.empty()) {
818 LogRequiredActions(required_actions);
819 delegate_->OnDidSaveInstrument(instrument_id,
820 required_actions,
821 form_errors);
822 } else {
823 HandleMalformedResponse();
824 }
825 break;
826 }
827
828 case SAVE_INSTRUMENT_AND_ADDRESS: {
829 std::string instrument_id; 704 std::string instrument_id;
830 response_dict->GetString(kInstrumentIdKey, &instrument_id); 705 response_dict->GetString(kInstrumentIdKey, &instrument_id);
831 std::string shipping_address_id; 706 std::string shipping_address_id;
832 response_dict->GetString(kShippingAddressIdKey, 707 response_dict->GetString(kShippingAddressIdKey,
833 &shipping_address_id); 708 &shipping_address_id);
834 std::vector<RequiredAction> required_actions; 709 std::vector<RequiredAction> required_actions;
835 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions); 710 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions);
836 std::vector<FormFieldError> form_errors; 711 std::vector<FormFieldError> form_errors;
837 GetFormFieldErrors(*response_dict, &form_errors); 712 GetFormFieldErrors(*response_dict, &form_errors);
838 if ((!instrument_id.empty() && !shipping_address_id.empty()) || 713 if (instrument_id.empty() && shipping_address_id.empty() &&
839 !required_actions.empty()) { 714 required_actions.empty()) {
715 HandleMalformedResponse();
716 } else {
840 LogRequiredActions(required_actions); 717 LogRequiredActions(required_actions);
841 delegate_->OnDidSaveInstrumentAndAddress(instrument_id, 718 delegate_->OnDidSaveToWallet(instrument_id,
842 shipping_address_id, 719 shipping_address_id,
843 required_actions, 720 required_actions,
844 form_errors); 721 form_errors);
845 } else {
846 HandleMalformedResponse();
847 } 722 }
848 break; 723 break;
849 } 724 }
850
851 case UPDATE_ADDRESS: {
852 std::string address_id;
853 std::vector<RequiredAction> required_actions;
854 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions);
855 std::vector<FormFieldError> form_errors;
856 GetFormFieldErrors(*response_dict, &form_errors);
857 if (response_dict->GetString(kShippingAddressIdKey, &address_id) ||
858 !required_actions.empty()) {
859 LogRequiredActions(required_actions);
860 delegate_->OnDidUpdateAddress(address_id,
861 required_actions,
862 form_errors);
863 } else {
864 HandleMalformedResponse();
865 }
866 break;
867 }
868
869 case UPDATE_INSTRUMENT: {
870 std::string instrument_id;
871 std::vector<RequiredAction> required_actions;
872 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions);
873 std::vector<FormFieldError> form_errors;
874 GetFormFieldErrors(*response_dict, &form_errors);
875 if (response_dict->GetString(kInstrumentIdKey, &instrument_id) ||
876 !required_actions.empty()) {
877 LogRequiredActions(required_actions);
878 delegate_->OnDidUpdateInstrument(instrument_id,
879 required_actions,
880 form_errors);
881 } else {
882 HandleMalformedResponse();
883 }
884 break;
885 }
886 725
887 case NO_PENDING_REQUEST: 726 case NO_PENDING_REQUEST:
888 NOTREACHED(); 727 NOTREACHED();
889 } 728 }
890 729
891 request_.reset(); 730 request_.reset();
892 StartNextPendingRequest(); 731 StartNextPendingRequest();
893 } 732 }
894 733
895 void WalletClient::StartNextPendingRequest() { 734 void WalletClient::StartNextPendingRequest() {
(...skipping 10 matching lines...) Expand all
906 request_->ReceivedContentWasMalformed(); 745 request_->ReceivedContentWasMalformed();
907 HandleWalletError(MALFORMED_RESPONSE); 746 HandleWalletError(MALFORMED_RESPONSE);
908 } 747 }
909 748
910 void WalletClient::HandleWalletError(WalletClient::ErrorType error_type) { 749 void WalletClient::HandleWalletError(WalletClient::ErrorType error_type) {
911 delegate_->OnWalletError(error_type); 750 delegate_->OnWalletError(error_type);
912 delegate_->GetMetricLogger().LogWalletErrorMetric( 751 delegate_->GetMetricLogger().LogWalletErrorMetric(
913 delegate_->GetDialogType(), ErrorTypeToUmaMetric(error_type)); 752 delegate_->GetDialogType(), ErrorTypeToUmaMetric(error_type));
914 } 753 }
915 754
916 void WalletClient::OnDidEncryptOneTimePad(
917 const std::string& encrypted_one_time_pad,
918 const std::string& session_material) {
919 DCHECK_EQ(GET_FULL_WALLET, request_type_);
920 pending_request_body_.SetString(kEncryptedOtpKey, encrypted_one_time_pad);
921 pending_request_body_.SetString(kSessionMaterialKey, session_material);
922
923 std::string post_body;
924 base::JSONWriter::Write(&pending_request_body_, &post_body);
925 pending_request_body_.Clear();
926
927 MakeWalletRequest(GetGetFullWalletUrl(), post_body);
928 }
929
930 void WalletClient::OnDidEscrowInstrumentInformation(
931 const std::string& escrow_handle) {
932 DCHECK(request_type_ == SAVE_INSTRUMENT ||
933 request_type_ == SAVE_INSTRUMENT_AND_ADDRESS);
934
935 pending_request_body_.SetString(kInstrumentEscrowHandleKey, escrow_handle);
936
937 std::string post_body;
938 base::JSONWriter::Write(&pending_request_body_, &post_body);
939 pending_request_body_.Clear();
940
941 MakeWalletRequest(GetSaveToWalletUrl(), post_body);
942 }
943
944 void WalletClient::OnDidEscrowCardVerificationNumber(
945 const std::string& escrow_handle) {
946 DCHECK(request_type_ == AUTHENTICATE_INSTRUMENT ||
947 request_type_ == UPDATE_INSTRUMENT);
948 pending_request_body_.SetString(kInstrumentEscrowHandleKey, escrow_handle);
949
950 std::string post_body;
951 base::JSONWriter::Write(&pending_request_body_, &post_body);
952 pending_request_body_.Clear();
953
954 if (request_type_ == AUTHENTICATE_INSTRUMENT)
955 MakeWalletRequest(GetAuthenticateInstrumentUrl(), post_body);
956 else
957 MakeWalletRequest(GetSaveToWalletUrl(), post_body);
958 }
959
960 void WalletClient::OnDidMakeRequest() {
961 delegate_->GetMetricLogger().LogWalletErrorMetric(
962 delegate_->GetDialogType(),
963 AutofillMetrics::WALLET_ERROR_BASELINE_ISSUED_REQUEST);
964 }
965
966 void WalletClient::OnNetworkError() {
967 HandleWalletError(NETWORK_ERROR);
968 }
969
970 void WalletClient::OnMalformedResponse() {
971 HandleWalletError(MALFORMED_RESPONSE);
972 }
973
974 // Logs an UMA metric for each of the |required_actions|. 755 // Logs an UMA metric for each of the |required_actions|.
975 void WalletClient::LogRequiredActions( 756 void WalletClient::LogRequiredActions(
976 const std::vector<RequiredAction>& required_actions) const { 757 const std::vector<RequiredAction>& required_actions) const {
977 for (size_t i = 0; i < required_actions.size(); ++i) { 758 for (size_t i = 0; i < required_actions.size(); ++i) {
978 delegate_->GetMetricLogger().LogWalletRequiredActionMetric( 759 delegate_->GetMetricLogger().LogWalletRequiredActionMetric(
979 delegate_->GetDialogType(), 760 delegate_->GetDialogType(),
980 RequiredActionToUmaMetric(required_actions[i])); 761 RequiredActionToUmaMetric(required_actions[i]));
981 } 762 }
982 } 763 }
983 764
984 AutofillMetrics::WalletApiCallMetric WalletClient::RequestTypeToUmaMetric( 765 AutofillMetrics::WalletApiCallMetric WalletClient::RequestTypeToUmaMetric(
985 RequestType request_type) const { 766 RequestType request_type) const {
986 switch (request_type) { 767 switch (request_type) {
987 case ACCEPT_LEGAL_DOCUMENTS: 768 case ACCEPT_LEGAL_DOCUMENTS:
988 return AutofillMetrics::ACCEPT_LEGAL_DOCUMENTS; 769 return AutofillMetrics::ACCEPT_LEGAL_DOCUMENTS;
989 case AUTHENTICATE_INSTRUMENT: 770 case AUTHENTICATE_INSTRUMENT:
990 return AutofillMetrics::AUTHENTICATE_INSTRUMENT; 771 return AutofillMetrics::AUTHENTICATE_INSTRUMENT;
991 case GET_FULL_WALLET: 772 case GET_FULL_WALLET:
992 return AutofillMetrics::GET_FULL_WALLET; 773 return AutofillMetrics::GET_FULL_WALLET;
993 case GET_WALLET_ITEMS: 774 case GET_WALLET_ITEMS:
994 return AutofillMetrics::GET_WALLET_ITEMS; 775 return AutofillMetrics::GET_WALLET_ITEMS;
995 case SAVE_ADDRESS: 776 case SAVE_TO_WALLET:
996 return AutofillMetrics::SAVE_ADDRESS; 777 return AutofillMetrics::SAVE_TO_WALLET;
997 case SAVE_INSTRUMENT:
998 return AutofillMetrics::SAVE_INSTRUMENT;
999 case SAVE_INSTRUMENT_AND_ADDRESS:
1000 return AutofillMetrics::SAVE_INSTRUMENT_AND_ADDRESS;
1001 case SEND_STATUS: 778 case SEND_STATUS:
1002 return AutofillMetrics::SEND_STATUS; 779 return AutofillMetrics::SEND_STATUS;
1003 case UPDATE_ADDRESS:
1004 return AutofillMetrics::UPDATE_ADDRESS;
1005 case UPDATE_INSTRUMENT:
1006 return AutofillMetrics::UPDATE_INSTRUMENT;
1007 case NO_PENDING_REQUEST: 780 case NO_PENDING_REQUEST:
1008 NOTREACHED(); 781 NOTREACHED();
1009 return AutofillMetrics::UNKNOWN_API_CALL; 782 return AutofillMetrics::UNKNOWN_API_CALL;
1010 } 783 }
1011 784
1012 NOTREACHED(); 785 NOTREACHED();
1013 return AutofillMetrics::UNKNOWN_API_CALL; 786 return AutofillMetrics::UNKNOWN_API_CALL;
1014 } 787 }
1015 788
1016 } // namespace wallet 789 } // namespace wallet
1017 } // namespace autofill 790 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698