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

Side by Side Diff: third_party/WebKit/Source/modules/payments/PaymentRequest.cpp

Issue 2500183002: Do not parse JSON in the browser. (Closed)
Patch Set: Use a Dictionary type in IDL Created 4 years, 1 month 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
« no previous file with comments | « third_party/WebKit/Source/modules/payments/PaymentRequest.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "modules/payments/PaymentRequest.h" 5 #include "modules/payments/PaymentRequest.h"
6 6
7 #include "bindings/core/v8/ExceptionState.h" 7 #include "bindings/core/v8/ExceptionState.h"
8 #include "bindings/core/v8/ScriptPromiseResolver.h" 8 #include "bindings/core/v8/ScriptPromiseResolver.h"
9 #include "bindings/core/v8/ScriptState.h" 9 #include "bindings/core/v8/ScriptState.h"
10 #include "bindings/core/v8/V8StringResource.h" 10 #include "bindings/core/v8/V8StringResource.h"
11 #include "bindings/modules/v8/V8AndroidPayMethodData.h"
11 #include "bindings/modules/v8/V8PaymentDetails.h" 12 #include "bindings/modules/v8/V8PaymentDetails.h"
12 #include "core/EventTypeNames.h" 13 #include "core/EventTypeNames.h"
13 #include "core/dom/DOMException.h" 14 #include "core/dom/DOMException.h"
14 #include "core/dom/ExceptionCode.h" 15 #include "core/dom/ExceptionCode.h"
15 #include "core/events/Event.h" 16 #include "core/events/Event.h"
16 #include "core/events/EventQueue.h" 17 #include "core/events/EventQueue.h"
17 #include "core/frame/FrameOwner.h" 18 #include "core/frame/FrameOwner.h"
18 #include "core/html/HTMLIFrameElement.h" 19 #include "core/html/HTMLIFrameElement.h"
19 #include "modules/EventTargetModulesNames.h" 20 #include "modules/EventTargetModulesNames.h"
21 #include "modules/payments/AndroidPayMethodData.h"
22 #include "modules/payments/AndroidPayTokenization.h"
20 #include "modules/payments/HTMLIFrameElementPayments.h" 23 #include "modules/payments/HTMLIFrameElementPayments.h"
21 #include "modules/payments/PaymentAddress.h" 24 #include "modules/payments/PaymentAddress.h"
22 #include "modules/payments/PaymentItem.h" 25 #include "modules/payments/PaymentItem.h"
23 #include "modules/payments/PaymentRequestUpdateEvent.h" 26 #include "modules/payments/PaymentRequestUpdateEvent.h"
24 #include "modules/payments/PaymentResponse.h" 27 #include "modules/payments/PaymentResponse.h"
25 #include "modules/payments/PaymentShippingOption.h" 28 #include "modules/payments/PaymentShippingOption.h"
26 #include "modules/payments/PaymentsValidators.h" 29 #include "modules/payments/PaymentsValidators.h"
27 #include "mojo/public/cpp/bindings/interface_request.h" 30 #include "mojo/public/cpp/bindings/interface_request.h"
28 #include "mojo/public/cpp/bindings/wtf_array.h" 31 #include "mojo/public/cpp/bindings/wtf_array.h"
29 #include "platform/mojo/MojoHelper.h" 32 #include "platform/mojo/MojoHelper.h"
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 output->shipping_type = PaymentShippingType::DELIVERY; 162 output->shipping_type = PaymentShippingType::DELIVERY;
160 else if (input.shippingType() == "pickup") 163 else if (input.shippingType() == "pickup")
161 output->shipping_type = PaymentShippingType::PICKUP; 164 output->shipping_type = PaymentShippingType::PICKUP;
162 else 165 else
163 output->shipping_type = PaymentShippingType::SHIPPING; 166 output->shipping_type = PaymentShippingType::SHIPPING;
164 167
165 return output; 168 return output;
166 } 169 }
167 }; 170 };
168 171
169 template <>
170 struct TypeConverter<WTFArray<PaymentMethodDataPtr>,
171 WTF::Vector<blink::PaymentRequest::MethodData>> {
172 static WTFArray<PaymentMethodDataPtr> Convert(
173 const WTF::Vector<blink::PaymentRequest::MethodData>& input) {
174 WTFArray<PaymentMethodDataPtr> output(input.size());
175 for (size_t i = 0; i < input.size(); ++i) {
176 output[i] = PaymentMethodData::New();
177 output[i]->supported_methods =
178 WTF::Vector<WTF::String>(input[i].supportedMethods);
179 output[i]->stringified_data = input[i].stringifiedData;
180 }
181 return output;
182 }
183 };
184
185 } // namespace mojo 172 } // namespace mojo
186 173
187 namespace blink { 174 namespace blink {
188 namespace { 175 namespace {
189 176
177 using payments::mojom::blink::AndroidPayCardNetwork;
178 using payments::mojom::blink::AndroidPayTokenization;
179
190 // If the website does not call complete() 60 seconds after show() has been 180 // If the website does not call complete() 60 seconds after show() has been
191 // resolved, then behave as if the website called complete("fail"). 181 // resolved, then behave as if the website called complete("fail").
192 static const int completeTimeoutSeconds = 60; 182 static const int completeTimeoutSeconds = 60;
193 183
184 const struct {
185 const AndroidPayCardNetwork code;
186 const char* name;
187 } kAndroidPayNetwork[] = {{AndroidPayCardNetwork::AMEX, "AMEX"},
188 {AndroidPayCardNetwork::DISCOVER, "DISCOVER"},
189 {AndroidPayCardNetwork::MASTERCARD, "MASTERCARD"},
190 {AndroidPayCardNetwork::VISA, "VISA"}};
191
192 const struct {
193 const AndroidPayTokenization code;
194 const char* name;
195 } kAndroidPayTokenization[] = {
196 {AndroidPayTokenization::GATEWAY_TOKEN, "GATEWAY_TOKEN"},
197 {AndroidPayTokenization::NETWORK_TOKEN, "NETWORK_TOKEN"}};
198
194 // Validates ShippingOption or PaymentItem, which happen to have identical 199 // Validates ShippingOption or PaymentItem, which happen to have identical
195 // fields, except for "id", which is present only in ShippingOption. 200 // fields, except for "id", which is present only in ShippingOption.
196 template <typename T> 201 template <typename T>
197 void validateShippingOptionOrPaymentItem(const T& item, 202 void validateShippingOptionOrPaymentItem(const T& item,
198 ExceptionState& exceptionState) { 203 ExceptionState& exceptionState) {
199 if (!item.hasLabel() || item.label().isEmpty()) { 204 if (!item.hasLabel() || item.label().isEmpty()) {
200 exceptionState.throwTypeError("Item label required"); 205 exceptionState.throwTypeError("Item label required");
201 return; 206 return;
202 } 207 }
203 208
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 347
343 String errorMessage; 348 String errorMessage;
344 if (!PaymentsValidators::isValidErrorMsgFormat(details.error(), 349 if (!PaymentsValidators::isValidErrorMsgFormat(details.error(),
345 &errorMessage)) { 350 &errorMessage)) {
346 exceptionState.throwTypeError(errorMessage); 351 exceptionState.throwTypeError(errorMessage);
347 } 352 }
348 353
349 return keepShippingOptions; 354 return keepShippingOptions;
350 } 355 }
351 356
357 void maybeSetAndroidPayMethodata(
358 const ScriptValue& input,
359 payments::mojom::blink::PaymentMethodDataPtr& output) {
360 AndroidPayMethodData androidPay;
361 TrackExceptionState exceptionState;
362 V8AndroidPayMethodData::toImpl(input.isolate(), input.v8Value(), androidPay,
363 exceptionState);
364 if (exceptionState.hadException())
365 return;
366
367 if (androidPay.hasEnvironment() && androidPay.environment() == "TEST")
368 output->environment = payments::mojom::blink::AndroidPayEnvironment::TEST;
369
370 output->merchant_name = androidPay.merchantName();
371 output->merchant_id = androidPay.merchantId();
372
373 if (androidPay.hasAllowedCardNetworks()) {
374 output->allowed_card_networks.resize(
375 androidPay.allowedCardNetworks().size());
376 size_t numberOfNetworks = 0;
377 for (size_t i = 0; i < androidPay.allowedCardNetworks().size(); ++i) {
378 for (size_t j = 0; j < arraysize(kAndroidPayNetwork); ++j) {
379 if (androidPay.allowedCardNetworks()[i] == kAndroidPayNetwork[j].name) {
380 output->allowed_card_networks[numberOfNetworks++] =
381 kAndroidPayNetwork[j].code;
382 break;
383 }
384 }
385 }
386 output->allowed_card_networks.resize(numberOfNetworks);
387 }
388
389 if (androidPay.hasPaymentMethodTokenizationParameters()) {
390 const blink::AndroidPayTokenization& tokenization =
391 androidPay.paymentMethodTokenizationParameters();
392 output->tokenization_type =
393 payments::mojom::blink::AndroidPayTokenization::UNSPECIFIED;
394 if (tokenization.hasTokenizationType()) {
395 for (size_t j = 0; j < arraysize(kAndroidPayTokenization); ++j) {
396 if (tokenization.tokenizationType() ==
397 kAndroidPayTokenization[j].name) {
398 output->tokenization_type = kAndroidPayTokenization[j].code;
399 break;
400 }
401 }
402 }
403
404 if (tokenization.hasParameters()) {
405 Vector<String> keys;
406 tokenization.parameters().getPropertyNames(keys);
407 output->parameters.resize(keys.size());
408 size_t numberOfParameters = 0;
409 String value;
410 for (size_t i = 0; i < keys.size(); ++i) {
411 if (!DictionaryHelper::get(tokenization.parameters(), keys[i], value))
412 continue;
413 output->parameters[numberOfParameters] =
414 payments::mojom::blink::AndroidPayTokenizationParameter::New();
415 output->parameters[numberOfParameters]->key = keys[i];
416 output->parameters[numberOfParameters]->value = value;
417 ++numberOfParameters;
418 }
419 output->parameters.resize(numberOfParameters);
420 }
421 }
422 }
423
352 void validateAndConvertPaymentMethodData( 424 void validateAndConvertPaymentMethodData(
353 const HeapVector<PaymentMethodData>& paymentMethodDataVector, 425 const HeapVector<PaymentMethodData>& input,
354 Vector<PaymentRequest::MethodData>* methodData, 426 Vector<payments::mojom::blink::PaymentMethodDataPtr>& output,
355 ExceptionState& exceptionState) { 427 ExceptionState& exceptionState) {
356 if (paymentMethodDataVector.isEmpty()) { 428 if (input.isEmpty()) {
357 exceptionState.throwTypeError( 429 exceptionState.throwTypeError(
358 "Must specify at least one payment method identifier"); 430 "Must specify at least one payment method identifier");
359 return; 431 return;
360 } 432 }
361 433
362 for (const auto& paymentMethodData : paymentMethodDataVector) { 434 output.resize(input.size());
435 for (size_t i = 0; i < input.size(); ++i) {
436 const auto& paymentMethodData = input[i];
363 if (paymentMethodData.supportedMethods().isEmpty()) { 437 if (paymentMethodData.supportedMethods().isEmpty()) {
364 exceptionState.throwTypeError( 438 exceptionState.throwTypeError(
365 "Must specify at least one payment method identifier"); 439 "Must specify at least one payment method identifier");
366 return; 440 return;
367 } 441 }
368 442
369 String stringifiedData = ""; 443 String stringifiedData = "";
370 if (paymentMethodData.hasData() && !paymentMethodData.data().isEmpty()) { 444 if (paymentMethodData.hasData() && !paymentMethodData.data().isEmpty()) {
371 if (!paymentMethodData.data().v8Value()->IsObject() || 445 if (!paymentMethodData.data().v8Value()->IsObject() ||
372 paymentMethodData.data().v8Value()->IsArray()) { 446 paymentMethodData.data().v8Value()->IsArray()) {
373 exceptionState.throwTypeError( 447 exceptionState.throwTypeError(
374 "Data should be a JSON-serializable object"); 448 "Data should be a JSON-serializable object");
375 return; 449 return;
376 } 450 }
377 451
378 v8::Local<v8::String> value; 452 v8::Local<v8::String> value;
379 if (!v8::JSON::Stringify( 453 if (!v8::JSON::Stringify(
380 paymentMethodData.data().context(), 454 paymentMethodData.data().context(),
381 paymentMethodData.data().v8Value().As<v8::Object>()) 455 paymentMethodData.data().v8Value().As<v8::Object>())
382 .ToLocal(&value)) { 456 .ToLocal(&value)) {
383 exceptionState.throwTypeError( 457 exceptionState.throwTypeError(
384 "Unable to parse payment method specific data"); 458 "Unable to parse payment method specific data");
385 return; 459 return;
386 } 460 }
387 stringifiedData = 461 stringifiedData =
388 v8StringToWebCoreString<String>(value, DoNotExternalize); 462 v8StringToWebCoreString<String>(value, DoNotExternalize);
389 } 463 }
390 methodData->append(PaymentRequest::MethodData( 464
391 paymentMethodData.supportedMethods(), stringifiedData)); 465 output[i] = payments::mojom::blink::PaymentMethodData::New();
466 output[i]->supported_methods = paymentMethodData.supportedMethods();
467 output[i]->stringified_data = stringifiedData;
468 maybeSetAndroidPayMethodata(paymentMethodData.data(), output[i]);
392 } 469 }
393 } 470 }
394 471
395 String getSelectedShippingOption(const PaymentDetails& details) { 472 String getSelectedShippingOption(const PaymentDetails& details) {
396 String result; 473 String result;
397 if (!details.hasShippingOptions()) 474 if (!details.hasShippingOptions())
398 return result; 475 return result;
399 476
400 for (int i = details.shippingOptions().size() - 1; i >= 0; --i) { 477 for (int i = details.shippingOptions().size() - 1; i >= 0; --i) {
401 if (details.shippingOptions()[i].hasSelected() && 478 if (details.shippingOptions()[i].hasSelected() &&
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 if (ownerElement && isHTMLIFrameElement(ownerElement)) { 525 if (ownerElement && isHTMLIFrameElement(ownerElement)) {
449 HTMLIFrameElement* iframe = toHTMLIFrameElement(ownerElement); 526 HTMLIFrameElement* iframe = toHTMLIFrameElement(ownerElement);
450 if (HTMLIFrameElementPayments::from(*iframe).allowPaymentRequest(*iframe)) 527 if (HTMLIFrameElementPayments::from(*iframe).allowPaymentRequest(*iframe))
451 return allowedToUsePaymentRequest(frame->tree().parent()); 528 return allowedToUsePaymentRequest(frame->tree().parent());
452 } 529 }
453 530
454 // 4. Return false. 531 // 4. Return false.
455 return false; 532 return false;
456 } 533 }
457 534
458 WTF::Vector<payments::mojom::blink::PaymentMethodDataPtr>
459 ConvertPaymentMethodData(
460 const Vector<PaymentRequest::MethodData>& blinkMethods) {
461 WTF::Vector<payments::mojom::blink::PaymentMethodDataPtr> mojoMethods(
462 blinkMethods.size());
463 for (size_t i = 0; i < blinkMethods.size(); ++i) {
464 mojoMethods[i] = payments::mojom::blink::PaymentMethodData::New();
465 mojoMethods[i]->supported_methods =
466 WTF::Vector<WTF::String>(blinkMethods[i].supportedMethods);
467 mojoMethods[i]->stringified_data = blinkMethods[i].stringifiedData;
468 }
469 return mojoMethods;
470 }
471
472 } // namespace 535 } // namespace
473 536
474 PaymentRequest* PaymentRequest::create( 537 PaymentRequest* PaymentRequest::create(
475 ScriptState* scriptState, 538 ScriptState* scriptState,
476 const HeapVector<PaymentMethodData>& methodData, 539 const HeapVector<PaymentMethodData>& methodData,
477 const PaymentDetails& details, 540 const PaymentDetails& details,
478 ExceptionState& exceptionState) { 541 ExceptionState& exceptionState) {
479 return new PaymentRequest(scriptState, methodData, details, PaymentOptions(), 542 return new PaymentRequest(scriptState, methodData, details, PaymentOptions(),
480 exceptionState); 543 exceptionState);
481 } 544 }
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 PaymentRequest::PaymentRequest(ScriptState* scriptState, 695 PaymentRequest::PaymentRequest(ScriptState* scriptState,
633 const HeapVector<PaymentMethodData>& methodData, 696 const HeapVector<PaymentMethodData>& methodData,
634 const PaymentDetails& details, 697 const PaymentDetails& details,
635 const PaymentOptions& options, 698 const PaymentOptions& options,
636 ExceptionState& exceptionState) 699 ExceptionState& exceptionState)
637 : ContextLifecycleObserver(scriptState->getExecutionContext()), 700 : ContextLifecycleObserver(scriptState->getExecutionContext()),
638 ActiveScriptWrappable(this), 701 ActiveScriptWrappable(this),
639 m_options(options), 702 m_options(options),
640 m_clientBinding(this), 703 m_clientBinding(this),
641 m_completeTimer(this, &PaymentRequest::onCompleteTimeout) { 704 m_completeTimer(this, &PaymentRequest::onCompleteTimeout) {
642 Vector<MethodData> validatedMethodData; 705 Vector<payments::mojom::blink::PaymentMethodDataPtr> validatedMethodData;
643 validateAndConvertPaymentMethodData(methodData, &validatedMethodData, 706 validateAndConvertPaymentMethodData(methodData, validatedMethodData,
644 exceptionState); 707 exceptionState);
645 if (exceptionState.hadException()) 708 if (exceptionState.hadException())
646 return; 709 return;
647 710
648 if (!scriptState->getExecutionContext()->isSecureContext()) { 711 if (!scriptState->getExecutionContext()->isSecureContext()) {
649 exceptionState.throwSecurityError("Must be in a secure context"); 712 exceptionState.throwSecurityError("Must be in a secure context");
650 return; 713 return;
651 } 714 }
652 715
653 if (!allowedToUsePaymentRequest(scriptState->domWindow()->frame())) { 716 if (!allowedToUsePaymentRequest(scriptState->domWindow()->frame())) {
(...skipping 18 matching lines...) Expand all
672 m_shippingType = getValidShippingType(m_options.shippingType()); 735 m_shippingType = getValidShippingType(m_options.shippingType());
673 } 736 }
674 737
675 scriptState->domWindow()->frame()->interfaceProvider()->getInterface( 738 scriptState->domWindow()->frame()->interfaceProvider()->getInterface(
676 mojo::GetProxy(&m_paymentProvider)); 739 mojo::GetProxy(&m_paymentProvider));
677 m_paymentProvider.set_connection_error_handler(convertToBaseCallback( 740 m_paymentProvider.set_connection_error_handler(convertToBaseCallback(
678 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this), 741 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this),
679 payments::mojom::blink::PaymentErrorReason::UNKNOWN))); 742 payments::mojom::blink::PaymentErrorReason::UNKNOWN)));
680 m_paymentProvider->Init( 743 m_paymentProvider->Init(
681 m_clientBinding.CreateInterfacePtrAndBind(), 744 m_clientBinding.CreateInterfacePtrAndBind(),
682 ConvertPaymentMethodData(validatedMethodData), 745 std::move(validatedMethodData),
683 maybeKeepShippingOptions( 746 maybeKeepShippingOptions(
684 payments::mojom::blink::PaymentDetails::From(details), 747 payments::mojom::blink::PaymentDetails::From(details),
685 keepShippingOptions && m_options.requestShipping()), 748 keepShippingOptions && m_options.requestShipping()),
686 payments::mojom::blink::PaymentOptions::From(m_options)); 749 payments::mojom::blink::PaymentOptions::From(m_options));
687 } 750 }
688 751
689 void PaymentRequest::contextDestroyed() { 752 void PaymentRequest::contextDestroyed() {
690 clearResolversAndCloseMojoConnection(); 753 clearResolversAndCloseMojoConnection();
691 } 754 }
692 755
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 m_completeTimer.stop(); 921 m_completeTimer.stop();
859 m_completeResolver.clear(); 922 m_completeResolver.clear();
860 m_showResolver.clear(); 923 m_showResolver.clear();
861 m_abortResolver.clear(); 924 m_abortResolver.clear();
862 if (m_clientBinding.is_bound()) 925 if (m_clientBinding.is_bound())
863 m_clientBinding.Close(); 926 m_clientBinding.Close();
864 m_paymentProvider.reset(); 927 m_paymentProvider.reset();
865 } 928 }
866 929
867 } // namespace blink 930 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/payments/PaymentRequest.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698