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

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: Raman's review 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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 const char kSelectedAddressIdKey[] = "selected_address_id"; 234 const char kSelectedAddressIdKey[] = "selected_address_id";
218 const char kSelectedInstrumentIdKey[] = "selected_instrument_id"; 235 const char kSelectedInstrumentIdKey[] = "selected_instrument_id";
219 const char kSessionMaterialKey[] = "session_material"; 236 const char kSessionMaterialKey[] = "session_material";
220 const char kShippingAddressIdKey[] = "shipping_address_id"; 237 const char kShippingAddressIdKey[] = "shipping_address_id";
221 const char kShippingAddressKey[] = "shipping_address"; 238 const char kShippingAddressKey[] = "shipping_address";
222 const char kAutocheckoutStepsKey[] = "steps"; 239 const char kAutocheckoutStepsKey[] = "steps";
223 const char kSuccessKey[] = "success"; 240 const char kSuccessKey[] = "success";
224 const char kUpgradedBillingAddressKey[] = "upgraded_billing_address"; 241 const char kUpgradedBillingAddressKey[] = "upgraded_billing_address";
225 const char kUpgradedInstrumentIdKey[] = "upgraded_instrument_id"; 242 const char kUpgradedInstrumentIdKey[] = "upgraded_instrument_id";
226 243
244 void UpdateInstrument(const Instrument& instrument,
245 base::DictionaryValue* request_dict) {
246 DCHECK(instrument.address() ||
247 (instrument.expiration_month() > 0 &&
248 instrument.expiration_year() > 0));
249
250 request_dict->SetString(kUpgradedInstrumentIdKey,
251 instrument.object_id());
252
253 if (instrument.address()) {
254 request_dict->SetString(kInstrumentPhoneNumberKey,
255 instrument.address()->phone_number());
256 request_dict->Set(
257 kUpgradedBillingAddressKey,
258 instrument.address()->ToDictionaryWithoutID().release());
259 }
260
261 if (instrument.expiration_month() > 0 && instrument.expiration_year() > 0) {
262 DCHECK(!instrument.card_verification_number().empty());
263 request_dict->SetInteger(kInstrumentExpMonthKey,
264 instrument.expiration_month());
265 request_dict->SetInteger(kInstrumentExpYearKey,
266 instrument.expiration_year());
267 }
268
269 if (request_dict->HasKey(kInstrumentKey))
270 request_dict->SetString(kInstrumentType, "CREDIT_CARD");
271 }
272
227 } // namespace 273 } // namespace
228 274
229 WalletClient::FullWalletRequest::FullWalletRequest( 275 WalletClient::FullWalletRequest::FullWalletRequest(
230 const std::string& instrument_id, 276 const std::string& instrument_id,
231 const std::string& address_id, 277 const std::string& address_id,
232 const GURL& source_url, 278 const GURL& source_url,
233 const std::string& google_transaction_id, 279 const std::string& google_transaction_id,
234 const std::vector<RiskCapability> risk_capabilities) 280 const std::vector<RiskCapability> risk_capabilities)
235 : instrument_id(instrument_id), 281 : instrument_id(instrument_id),
236 address_id(address_id), 282 address_id(address_id),
237 source_url(source_url), 283 source_url(source_url),
238 google_transaction_id(google_transaction_id), 284 google_transaction_id(google_transaction_id),
239 risk_capabilities(risk_capabilities) {} 285 risk_capabilities(risk_capabilities) {}
240 286
241 WalletClient::FullWalletRequest::~FullWalletRequest() {} 287 WalletClient::FullWalletRequest::~FullWalletRequest() {}
242 288
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, 289 WalletClient::WalletClient(net::URLRequestContextGetter* context_getter,
254 WalletClientDelegate* delegate) 290 WalletClientDelegate* delegate)
255 : context_getter_(context_getter), 291 : context_getter_(context_getter),
256 delegate_(delegate), 292 delegate_(delegate),
257 request_type_(NO_PENDING_REQUEST), 293 request_type_(NO_PENDING_REQUEST),
258 one_time_pad_(kOneTimePadLength), 294 one_time_pad_(kOneTimePadLength) {
259 encryption_escrow_client_(context_getter, this) {
260 DCHECK(context_getter_.get()); 295 DCHECK(context_getter_.get());
261 DCHECK(delegate_); 296 DCHECK(delegate_);
262 } 297 }
263 298
264 WalletClient::~WalletClient() {} 299 WalletClient::~WalletClient() {}
265 300
266 void WalletClient::AcceptLegalDocuments( 301 void WalletClient::AcceptLegalDocuments(
267 const std::vector<WalletItems::LegalDocument*>& documents, 302 const std::vector<WalletItems::LegalDocument*>& documents,
268 const std::string& google_transaction_id, 303 const std::string& google_transaction_id,
269 const GURL& source_url) { 304 const GURL& source_url) {
270 if (documents.empty()) 305 if (documents.empty())
271 return; 306 return;
272 307
273 std::vector<std::string> document_ids; 308 std::vector<std::string> document_ids;
274 for (size_t i = 0; i < documents.size(); ++i) { 309 for (size_t i = 0; i < documents.size(); ++i) {
275 document_ids.push_back(documents[i]->id()); 310 document_ids.push_back(documents[i]->id());
276 } 311 }
277 DoAcceptLegalDocuments(document_ids, google_transaction_id, source_url); 312 DoAcceptLegalDocuments(document_ids, google_transaction_id, source_url);
278 } 313 }
279 314
280 void WalletClient::AuthenticateInstrument( 315 void WalletClient::AuthenticateInstrument(
281 const std::string& instrument_id, 316 const std::string& instrument_id,
282 const std::string& card_verification_number, 317 const std::string& card_verification_number) {
283 const std::string& obfuscated_gaia_id) {
284 if (HasRequestInProgress()) { 318 if (HasRequestInProgress()) {
285 pending_requests_.push(base::Bind(&WalletClient::AuthenticateInstrument, 319 pending_requests_.push(base::Bind(&WalletClient::AuthenticateInstrument,
286 base::Unretained(this), 320 base::Unretained(this),
287 instrument_id, 321 instrument_id,
288 card_verification_number, 322 card_verification_number));
289 obfuscated_gaia_id));
290 return; 323 return;
291 } 324 }
292 325
293 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); 326 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
294 DCHECK(pending_request_body_.empty());
295 request_type_ = AUTHENTICATE_INSTRUMENT; 327 request_type_ = AUTHENTICATE_INSTRUMENT;
296 328
297 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); 329 base::DictionaryValue request_dict;
298 pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData()); 330 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
299 pending_request_body_.SetString(kInstrumentIdKey, instrument_id); 331 request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData());
332 request_dict.SetString(kInstrumentIdKey, instrument_id);
300 333
301 encryption_escrow_client_.EscrowCardVerificationNumber( 334 std::string json_payload;
302 card_verification_number, obfuscated_gaia_id); 335 base::JSONWriter::Write(&request_dict, &json_payload);
336
337 std::string escaped_card_verification_number = net::EscapeUrlEncodedData(
338 card_verification_number, true);
339
340 std::string post_body = base::StringPrintf(
341 kEscrowSensitiveInformationFormat,
342 net::EscapeUrlEncodedData(json_payload, true).c_str(),
343 escaped_card_verification_number.c_str(),
344 std::string().c_str());
345
346 MakeWalletRequest(GetAuthenticateInstrumentUrl(),
347 post_body,
348 kFormEncodedMimeType);
303 } 349 }
304 350
305 void WalletClient::GetFullWallet(const FullWalletRequest& full_wallet_request) { 351 void WalletClient::GetFullWallet(const FullWalletRequest& full_wallet_request) {
306 if (HasRequestInProgress()) { 352 if (HasRequestInProgress()) {
307 pending_requests_.push(base::Bind(&WalletClient::GetFullWallet, 353 pending_requests_.push(base::Bind(&WalletClient::GetFullWallet,
308 base::Unretained(this), 354 base::Unretained(this),
309 full_wallet_request)); 355 full_wallet_request));
310 return; 356 return;
311 } 357 }
312 358
313 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); 359 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
314 DCHECK(pending_request_body_.empty());
315 request_type_ = GET_FULL_WALLET; 360 request_type_ = GET_FULL_WALLET;
316 361
317 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); 362 base::DictionaryValue request_dict;
318 pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData()); 363 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
319 pending_request_body_.SetString(kSelectedInstrumentIdKey, 364 request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData());
320 full_wallet_request.instrument_id); 365 request_dict.SetString(kSelectedInstrumentIdKey,
321 pending_request_body_.SetString(kSelectedAddressIdKey, 366 full_wallet_request.instrument_id);
322 full_wallet_request.address_id); 367 request_dict.SetString(kSelectedAddressIdKey, full_wallet_request.address_id);
323 pending_request_body_.SetString( 368 request_dict.SetString(
324 kMerchantDomainKey, 369 kMerchantDomainKey,
325 full_wallet_request.source_url.GetWithEmptyPath().spec()); 370 full_wallet_request.source_url.GetWithEmptyPath().spec());
326 pending_request_body_.SetString(kGoogleTransactionIdKey, 371 request_dict.SetString(kGoogleTransactionIdKey,
327 full_wallet_request.google_transaction_id); 372 full_wallet_request.google_transaction_id);
328 pending_request_body_.SetString( 373 request_dict.SetString(kFeatureKey,
329 kFeatureKey, 374 DialogTypeToFeatureString(delegate_->GetDialogType()));
330 DialogTypeToFeatureString(delegate_->GetDialogType()));
331 375
332 scoped_ptr<base::ListValue> risk_capabilities_list(new base::ListValue()); 376 scoped_ptr<base::ListValue> risk_capabilities_list(new base::ListValue());
333 for (std::vector<RiskCapability>::const_iterator it = 377 for (std::vector<RiskCapability>::const_iterator it =
334 full_wallet_request.risk_capabilities.begin(); 378 full_wallet_request.risk_capabilities.begin();
335 it != full_wallet_request.risk_capabilities.end(); 379 it != full_wallet_request.risk_capabilities.end();
336 ++it) { 380 ++it) {
337 risk_capabilities_list->AppendString(RiskCapabilityToString(*it)); 381 risk_capabilities_list->AppendString(RiskCapabilityToString(*it));
338 } 382 }
339 pending_request_body_.Set(kRiskCapabilitiesKey, 383 request_dict.Set(kRiskCapabilitiesKey, risk_capabilities_list.release());
340 risk_capabilities_list.release()); 384
385 std::string json_payload;
386 base::JSONWriter::Write(&request_dict, &json_payload);
341 387
342 crypto::RandBytes(&(one_time_pad_[0]), one_time_pad_.size()); 388 crypto::RandBytes(&(one_time_pad_[0]), one_time_pad_.size());
343 encryption_escrow_client_.EncryptOneTimePad(one_time_pad_); 389
390 size_t num_bits = one_time_pad_.size() * 8;
391 DCHECK_LE(num_bits, kMaxBits);
392 DCHECK_GE(num_bits, kMinBits);
393
394 std::string post_body = base::StringPrintf(
395 kGetFullWalletRequestFormat,
396 net::EscapeUrlEncodedData(json_payload, true).c_str(),
397 base::HexEncode(&num_bits, 1).c_str(),
398 base::HexEncode(&(one_time_pad_[0]), one_time_pad_.size()).c_str());
399
400 MakeWalletRequest(GetGetFullWalletUrl(), post_body, kFormEncodedMimeType);
344 } 401 }
345 402
346 void WalletClient::GetWalletItems(const GURL& source_url) { 403 void WalletClient::SaveToWallet(scoped_ptr<Instrument> instrument,
404 scoped_ptr<Address> address,
405 const GURL& source_url) {
406 DCHECK(instrument || address);
347 if (HasRequestInProgress()) { 407 if (HasRequestInProgress()) {
348 pending_requests_.push(base::Bind(&WalletClient::GetWalletItems, 408 pending_requests_.push(base::Bind(&WalletClient::SaveToWallet,
349 base::Unretained(this), 409 base::Unretained(this),
410 base::Passed(&instrument),
411 base::Passed(&address),
350 source_url)); 412 source_url));
351 return; 413 return;
352 } 414 }
353 415
354 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); 416 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
355 request_type_ = GET_WALLET_ITEMS; 417 request_type_ = SAVE_TO_WALLET;
356 418
357 base::DictionaryValue request_dict; 419 base::DictionaryValue request_dict;
358 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey()); 420 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()); 421 request_dict.SetString(kRiskParamsKey, delegate_->GetRiskData());
384 request_dict.SetString(kMerchantDomainKey, 422 request_dict.SetString(kMerchantDomainKey,
385 source_url.GetWithEmptyPath().spec()); 423 source_url.GetWithEmptyPath().spec());
386 424
387 request_dict.Set(kShippingAddressKey, 425 std::string primary_account_number;
388 shipping_address.ToDictionaryWithID().release()); 426 std::string card_verification_number;
427 if (instrument) {
428 primary_account_number = net::EscapeUrlEncodedData(
429 UTF16ToUTF8(instrument->primary_account_number()), true);
430 card_verification_number = net::EscapeUrlEncodedData(
431 UTF16ToUTF8(instrument->card_verification_number()), true);
432 if (instrument->object_id().empty()) {
433 request_dict.Set(kInstrumentKey, instrument->ToDictionary().release());
434 request_dict.SetString(kInstrumentPhoneNumberKey,
435 instrument->address()->phone_number());
436 } else {
437 UpdateInstrument(*instrument, &request_dict);
438 }
439 }
440 if (address) {
441 request_dict.Set(kShippingAddressKey,
442 address->ToDictionaryWithID().release());
443 }
389 444
390 std::string post_body;
391 base::JSONWriter::Write(&request_dict, &post_body);
392 445
393 MakeWalletRequest(GetSaveToWalletUrl(), post_body); 446 std::string json_payload;
447 base::JSONWriter::Write(&request_dict, &json_payload);
448
449 std::string post_body = base::StringPrintf(
450 kEscrowSensitiveInformationFormat,
451 net::EscapeUrlEncodedData(json_payload, true).c_str(),
452 card_verification_number.c_str(),
453 primary_account_number.c_str());
454
455 MakeWalletRequest(GetSaveToWalletUrl(), post_body, kFormEncodedMimeType);
394 } 456 }
395 457
396 void WalletClient::SaveInstrument( 458 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()) { 459 if (HasRequestInProgress()) {
401 pending_requests_.push(base::Bind(&WalletClient::SaveInstrument, 460 pending_requests_.push(base::Bind(&WalletClient::GetWalletItems,
402 base::Unretained(this), 461 base::Unretained(this),
403 instrument,
404 obfuscated_gaia_id,
405 source_url)); 462 source_url));
406 return; 463 return;
407 } 464 }
408 465
409 DCHECK_EQ(NO_PENDING_REQUEST, request_type_); 466 DCHECK_EQ(NO_PENDING_REQUEST, request_type_);
410 DCHECK(pending_request_body_.empty()); 467 request_type_ = GET_WALLET_ITEMS;
411 request_type_ = SAVE_INSTRUMENT;
412 468
413 pending_request_body_.SetString(kApiKeyKey, google_apis::GetAPIKey()); 469 base::DictionaryValue request_dict;
414 pending_request_body_.SetString(kRiskParamsKey, delegate_->GetRiskData()); 470 request_dict.SetString(kApiKeyKey, google_apis::GetAPIKey());
415 pending_request_body_.SetString(kMerchantDomainKey, 471 request_dict.SetString(kMerchantDomainKey,
416 source_url.GetWithEmptyPath().spec()); 472 source_url.GetWithEmptyPath().spec());
417 473
418 pending_request_body_.Set(kInstrumentKey, 474 std::string post_body;
419 instrument.ToDictionary().release()); 475 base::JSONWriter::Write(&request_dict, &post_body);
420 pending_request_body_.SetString(kInstrumentPhoneNumberKey,
421 instrument.address().phone_number());
422 476
423 encryption_escrow_client_.EscrowInstrumentInformation(instrument, 477 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 } 478 }
462 479
463 void WalletClient::SendAutocheckoutStatus( 480 void WalletClient::SendAutocheckoutStatus(
464 AutocheckoutStatus status, 481 AutocheckoutStatus status,
465 const GURL& source_url, 482 const GURL& source_url,
466 const std::vector<AutocheckoutStatistic>& latency_statistics, 483 const std::vector<AutocheckoutStatistic>& latency_statistics,
467 const std::string& google_transaction_id) { 484 const std::string& google_transaction_id) {
468 DVLOG(1) << "Sending Autocheckout Status: " << status 485 DVLOG(1) << "Sending Autocheckout Status: " << status
469 << " for: " << source_url; 486 << " for: " << source_url;
470 if (HasRequestInProgress()) { 487 if (HasRequestInProgress()) {
(...skipping 25 matching lines...) Expand all
496 latency_statistics[i].ToDictionary().release()); 513 latency_statistics[i].ToDictionary().release());
497 } 514 }
498 request_dict.Set(kAutocheckoutStepsKey, 515 request_dict.Set(kAutocheckoutStepsKey,
499 latency_statistics_json.release()); 516 latency_statistics_json.release());
500 } 517 }
501 request_dict.SetString(kGoogleTransactionIdKey, google_transaction_id); 518 request_dict.SetString(kGoogleTransactionIdKey, google_transaction_id);
502 519
503 std::string post_body; 520 std::string post_body;
504 base::JSONWriter::Write(&request_dict, &post_body); 521 base::JSONWriter::Write(&request_dict, &post_body);
505 522
506 MakeWalletRequest(GetSendStatusUrl(), post_body); 523 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 } 524 }
605 525
606 bool WalletClient::HasRequestInProgress() const { 526 bool WalletClient::HasRequestInProgress() const {
607 // |SaveInstrument*()| and |UpdateInstrument()| methods don't set |request_| 527 return !!request_;
Dane Wallinga 2013/07/01 23:00:07 why not just return request_?
ahutter 2013/07/01 23:15:16 better to actually convert to a bool or so i'm tol
Dane Wallinga 2013/07/01 23:33:13 I find it more than a little horrifying that the b
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 } 528 }
612 529
613 void WalletClient::CancelRequests() { 530 void WalletClient::CancelRequests() {
614 encryption_escrow_client_.CancelRequest();
615 pending_request_body_.Clear();
616 request_.reset(); 531 request_.reset();
617 request_type_ = NO_PENDING_REQUEST; 532 request_type_ = NO_PENDING_REQUEST;
618 while (!pending_requests_.empty()) { 533 while (!pending_requests_.empty()) {
619 pending_requests_.pop(); 534 pending_requests_.pop();
620 } 535 }
621 } 536 }
622 537
623 void WalletClient::DoAcceptLegalDocuments( 538 void WalletClient::DoAcceptLegalDocuments(
624 const std::vector<std::string>& document_ids, 539 const std::vector<std::string>& document_ids,
625 const std::string& google_transaction_id, 540 const std::string& google_transaction_id,
(...skipping 19 matching lines...) Expand all
645 for (std::vector<std::string>::const_iterator it = document_ids.begin(); 560 for (std::vector<std::string>::const_iterator it = document_ids.begin();
646 it != document_ids.end(); ++it) { 561 it != document_ids.end(); ++it) {
647 if (!it->empty()) 562 if (!it->empty())
648 docs_list->AppendString(*it); 563 docs_list->AppendString(*it);
649 } 564 }
650 request_dict.Set(kAcceptedLegalDocumentKey, docs_list.release()); 565 request_dict.Set(kAcceptedLegalDocumentKey, docs_list.release());
651 566
652 std::string post_body; 567 std::string post_body;
653 base::JSONWriter::Write(&request_dict, &post_body); 568 base::JSONWriter::Write(&request_dict, &post_body);
654 569
655 MakeWalletRequest(GetAcceptLegalDocumentsUrl(), post_body); 570 MakeWalletRequest(GetAcceptLegalDocumentsUrl(), post_body, kJsonMimeType);
656 } 571 }
657 572
658 void WalletClient::MakeWalletRequest(const GURL& url, 573 void WalletClient::MakeWalletRequest(const GURL& url,
659 const std::string& post_body) { 574 const std::string& post_body,
575 const std::string& mime_type) {
660 DCHECK(!HasRequestInProgress()); 576 DCHECK(!HasRequestInProgress());
661 577
662 request_.reset(net::URLFetcher::Create( 578 request_.reset(net::URLFetcher::Create(
663 0, url, net::URLFetcher::POST, this)); 579 0, url, net::URLFetcher::POST, this));
664 request_->SetRequestContext(context_getter_.get()); 580 request_->SetRequestContext(context_getter_.get());
665 DVLOG(1) << "Making request to " << url << " with post_body=" << post_body; 581 DVLOG(1) << "Making request to " << url << " with post_body=" << post_body;
666 request_->SetUploadData(kJsonMimeType, post_body); 582 request_->SetUploadData(mime_type, post_body);
667 request_started_timestamp_ = base::Time::Now(); 583 request_started_timestamp_ = base::Time::Now();
668 request_->Start(); 584 request_->Start();
669 585
670 delegate_->GetMetricLogger().LogWalletErrorMetric( 586 delegate_->GetMetricLogger().LogWalletErrorMetric(
671 delegate_->GetDialogType(), 587 delegate_->GetDialogType(),
672 AutofillMetrics::WALLET_ERROR_BASELINE_ISSUED_REQUEST); 588 AutofillMetrics::WALLET_ERROR_BASELINE_ISSUED_REQUEST);
673 delegate_->GetMetricLogger().LogWalletRequiredActionMetric( 589 delegate_->GetMetricLogger().LogWalletRequiredActionMetric(
674 delegate_->GetDialogType(), 590 delegate_->GetDialogType(),
675 AutofillMetrics::WALLET_REQUIRED_ACTION_BASELINE_ISSUED_REQUEST); 591 AutofillMetrics::WALLET_REQUIRED_ACTION_BASELINE_ISSUED_REQUEST);
676 } 592 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 WalletItems::CreateWalletItems(*response_dict)); 697 WalletItems::CreateWalletItems(*response_dict));
782 if (wallet_items) { 698 if (wallet_items) {
783 LogRequiredActions(wallet_items->required_actions()); 699 LogRequiredActions(wallet_items->required_actions());
784 delegate_->OnDidGetWalletItems(wallet_items.Pass()); 700 delegate_->OnDidGetWalletItems(wallet_items.Pass());
785 } else { 701 } else {
786 HandleMalformedResponse(); 702 HandleMalformedResponse();
787 } 703 }
788 break; 704 break;
789 } 705 }
790 706
791 case SAVE_ADDRESS: { 707 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; 708 std::string instrument_id;
830 response_dict->GetString(kInstrumentIdKey, &instrument_id); 709 response_dict->GetString(kInstrumentIdKey, &instrument_id);
831 std::string shipping_address_id; 710 std::string shipping_address_id;
832 response_dict->GetString(kShippingAddressIdKey, 711 response_dict->GetString(kShippingAddressIdKey,
833 &shipping_address_id); 712 &shipping_address_id);
834 std::vector<RequiredAction> required_actions; 713 std::vector<RequiredAction> required_actions;
835 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions); 714 GetRequiredActionsForSaveToWallet(*response_dict, &required_actions);
836 std::vector<FormFieldError> form_errors; 715 std::vector<FormFieldError> form_errors;
837 GetFormFieldErrors(*response_dict, &form_errors); 716 GetFormFieldErrors(*response_dict, &form_errors);
838 if ((!instrument_id.empty() && !shipping_address_id.empty()) || 717 if (instrument_id.empty() && shipping_address_id.empty() &&
839 !required_actions.empty()) { 718 required_actions.empty()) {
719 HandleMalformedResponse();
720 } else {
840 LogRequiredActions(required_actions); 721 LogRequiredActions(required_actions);
841 delegate_->OnDidSaveInstrumentAndAddress(instrument_id, 722 delegate_->OnDidSaveToWallet(instrument_id,
842 shipping_address_id, 723 shipping_address_id,
843 required_actions, 724 required_actions,
844 form_errors); 725 form_errors);
845 } else {
846 HandleMalformedResponse();
847 } 726 }
848 break; 727 break;
849 } 728 }
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 729
887 case NO_PENDING_REQUEST: 730 case NO_PENDING_REQUEST:
888 NOTREACHED(); 731 NOTREACHED();
889 } 732 }
890 733
891 request_.reset(); 734 request_.reset();
892 StartNextPendingRequest(); 735 StartNextPendingRequest();
893 } 736 }
894 737
895 void WalletClient::StartNextPendingRequest() { 738 void WalletClient::StartNextPendingRequest() {
(...skipping 10 matching lines...) Expand all
906 request_->ReceivedContentWasMalformed(); 749 request_->ReceivedContentWasMalformed();
907 HandleWalletError(MALFORMED_RESPONSE); 750 HandleWalletError(MALFORMED_RESPONSE);
908 } 751 }
909 752
910 void WalletClient::HandleWalletError(WalletClient::ErrorType error_type) { 753 void WalletClient::HandleWalletError(WalletClient::ErrorType error_type) {
911 delegate_->OnWalletError(error_type); 754 delegate_->OnWalletError(error_type);
912 delegate_->GetMetricLogger().LogWalletErrorMetric( 755 delegate_->GetMetricLogger().LogWalletErrorMetric(
913 delegate_->GetDialogType(), ErrorTypeToUmaMetric(error_type)); 756 delegate_->GetDialogType(), ErrorTypeToUmaMetric(error_type));
914 } 757 }
915 758
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|. 759 // Logs an UMA metric for each of the |required_actions|.
975 void WalletClient::LogRequiredActions( 760 void WalletClient::LogRequiredActions(
976 const std::vector<RequiredAction>& required_actions) const { 761 const std::vector<RequiredAction>& required_actions) const {
977 for (size_t i = 0; i < required_actions.size(); ++i) { 762 for (size_t i = 0; i < required_actions.size(); ++i) {
978 delegate_->GetMetricLogger().LogWalletRequiredActionMetric( 763 delegate_->GetMetricLogger().LogWalletRequiredActionMetric(
979 delegate_->GetDialogType(), 764 delegate_->GetDialogType(),
980 RequiredActionToUmaMetric(required_actions[i])); 765 RequiredActionToUmaMetric(required_actions[i]));
981 } 766 }
982 } 767 }
983 768
984 AutofillMetrics::WalletApiCallMetric WalletClient::RequestTypeToUmaMetric( 769 AutofillMetrics::WalletApiCallMetric WalletClient::RequestTypeToUmaMetric(
985 RequestType request_type) const { 770 RequestType request_type) const {
986 switch (request_type) { 771 switch (request_type) {
987 case ACCEPT_LEGAL_DOCUMENTS: 772 case ACCEPT_LEGAL_DOCUMENTS:
988 return AutofillMetrics::ACCEPT_LEGAL_DOCUMENTS; 773 return AutofillMetrics::ACCEPT_LEGAL_DOCUMENTS;
989 case AUTHENTICATE_INSTRUMENT: 774 case AUTHENTICATE_INSTRUMENT:
990 return AutofillMetrics::AUTHENTICATE_INSTRUMENT; 775 return AutofillMetrics::AUTHENTICATE_INSTRUMENT;
991 case GET_FULL_WALLET: 776 case GET_FULL_WALLET:
992 return AutofillMetrics::GET_FULL_WALLET; 777 return AutofillMetrics::GET_FULL_WALLET;
993 case GET_WALLET_ITEMS: 778 case GET_WALLET_ITEMS:
994 return AutofillMetrics::GET_WALLET_ITEMS; 779 return AutofillMetrics::GET_WALLET_ITEMS;
995 case SAVE_ADDRESS: 780 case SAVE_TO_WALLET:
996 return AutofillMetrics::SAVE_ADDRESS; 781 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: 782 case SEND_STATUS:
1002 return AutofillMetrics::SEND_STATUS; 783 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: 784 case NO_PENDING_REQUEST:
1008 NOTREACHED(); 785 NOTREACHED();
1009 return AutofillMetrics::UNKNOWN_API_CALL; 786 return AutofillMetrics::UNKNOWN_API_CALL;
1010 } 787 }
1011 788
1012 NOTREACHED(); 789 NOTREACHED();
1013 return AutofillMetrics::UNKNOWN_API_CALL; 790 return AutofillMetrics::UNKNOWN_API_CALL;
1014 } 791 }
1015 792
1016 } // namespace wallet 793 } // namespace wallet
1017 } // namespace autofill 794 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698