Skip to content

Commit

Permalink
Merge branch 'develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
thomas-kl1 authored Apr 12, 2021
2 parents 8c81877 + 4cbf69f commit 5ddbc7c
Show file tree
Hide file tree
Showing 90 changed files with 3,400 additions and 14 deletions.
7 changes: 7 additions & 0 deletions ReCaptchaAdminUi/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,11 @@
</argument>
</arguments>
</virtualType>
<type name="Magento\ReCaptchaUi\Model\CaptchaTypeResolver">
<arguments>
<argument name="resolvers" xsi:type="array">
<item name="admin" xsi:type="object">Magento\ReCaptchaAdminUi\Model\CaptchaTypeResolver</item>
</argument>
</arguments>
</type>
</config>
20 changes: 15 additions & 5 deletions ReCaptchaCheckout/Block/LayoutProcessor/Checkout/Onepage.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,7 @@ public function __construct(
}

/**
* {@inheritdoc}
*
* @param array $jsLayout
* @return array
* @throws InputException
* @inheritDoc
*/
public function process($jsLayout): array
{
Expand Down Expand Up @@ -77,6 +73,20 @@ public function process($jsLayout): array
}
}

$key = 'place_order';
if ($this->isCaptchaEnabled->isCaptchaEnabledFor($key)) {
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
['payment']['children']['beforeMethods']['children']['place-order-recaptcha-container']['children']
['place-order-recaptcha']['settings'] = $this->captchaUiConfigResolver->get($key);
} else {
if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
['payment']['children']['beforeMethods']['children']['place-order-recaptcha'])) {
unset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
['payment']['children']['beforeMethods']['children']['place-order-recaptcha-container']
['children']['place-order-recaptcha']);
}
}

return $jsLayout;
}
}
61 changes: 61 additions & 0 deletions ReCaptchaCheckout/Model/WebapiConfigProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\ReCaptchaCheckout\Model;

use Magento\ReCaptchaUi\Model\IsCaptchaEnabledInterface;
use Magento\ReCaptchaUi\Model\ValidationConfigResolverInterface;
use Magento\ReCaptchaValidationApi\Api\Data\ValidationConfigInterface;
use Magento\ReCaptchaWebapiApi\Api\Data\EndpointInterface;
use Magento\ReCaptchaWebapiApi\Api\WebapiValidationConfigProviderInterface;

/**
* Provide checkout related endpoint configuration.
*/
class WebapiConfigProvider implements WebapiValidationConfigProviderInterface
{
private const CAPTCHA_ID = 'place_order';

/**
* @var IsCaptchaEnabledInterface
*/
private $isEnabled;

/**
* @var ValidationConfigResolverInterface
*/
private $configResolver;

/**
* @param IsCaptchaEnabledInterface $isEnabled
* @param ValidationConfigResolverInterface $configResolver
*/
public function __construct(IsCaptchaEnabledInterface $isEnabled, ValidationConfigResolverInterface $configResolver)
{
$this->isEnabled = $isEnabled;
$this->configResolver = $configResolver;
}

/**
* @inheritDoc
*/
public function getConfigFor(EndpointInterface $endpoint): ?ValidationConfigInterface
{
//phpcs:disable Magento2.PHP.LiteralNamespaces
if ($endpoint->getServiceMethod() === 'savePaymentInformationAndPlaceOrder'
|| $endpoint->getServiceClass() === 'Magento\QuoteGraphQl\Model\Resolver\SetPaymentAndPlaceOrder'
|| $endpoint->getServiceClass() === 'Magento\QuoteGraphQl\Model\Resolver\PlaceOrder'
) {
if ($this->isEnabled->isCaptchaEnabledFor(self::CAPTCHA_ID)) {
return $this->configResolver->get(self::CAPTCHA_ID);
}
}
//phpcs:enable Magento2.PHP.LiteralNamespaces

return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\ReCaptchaCheckout\Test\Api;

use Magento\Framework\Webapi\Rest\Request;
use Magento\Quote\Model\Quote;
use Magento\Quote\Model\QuoteFactory;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\TestCase\WebapiAbstract;

/**
* Test that checkout APIs are covered with ReCaptcha
*/
class GuestPaymentInformationManagementTest extends WebapiAbstract
{
private const API_ROUTE = '/V1/guest-carts/%s/payment-information';

/**
* @var QuoteFactory
*/
private $quoteFactory;

/**
* @inheritDoc
*/
protected function setUp(): void
{
parent::setUp();

$this->_markTestAsRestOnly();
$objectManager = Bootstrap::getObjectManager();
$this->quoteFactory = $objectManager->get(QuoteFactory::class);
}

/**
* @magentoApiDataFixture Magento/Checkout/_files/quote_with_check_payment.php
* @magentoConfigFixture default_store customer/captcha/enable 0
* @magentoConfigFixture base_website recaptcha_frontend/type_invisible/public_key test_public_key
* @magentoConfigFixture base_website recaptcha_frontend/type_invisible/private_key test_private_key
* @magentoConfigFixture base_website recaptcha_frontend/type_for/place_order invisible
*/
public function testRequired(): void
{
$this->expectException(\Throwable::class);
$this->expectExceptionCode(400);
$this->expectExceptionMessage('{"message":"ReCaptcha validation failed, please try again"}');

/** @var Quote $quote */
$quote = $this->quoteFactory->create();
$quote->load('test_order_1', 'reserved_order_id');
$cartId = $quote->getId();
$payment = $quote->getPayment();
$address = $quote->getBillingAddress();
$addressData = [];
$addressProperties = [
'city', 'company', 'countryId', 'firstname', 'lastname', 'postcode',
'region', 'regionCode', 'regionId', 'saveInAddressBook', 'street', 'telephone', 'email'
];
foreach ($addressProperties as $property) {
$method = 'get' . $property;
$addressData[$property] = $address->$method();
}

$serviceInfo = [
'rest' => [
'resourcePath' => sprintf(self::API_ROUTE, $cartId),
'httpMethod' => Request::HTTP_METHOD_POST,
'token' => null
],
];
$requestData = [
'cart_id' => $cartId,
'billingAddress' => $addressData,
'email' => $quote->getCustomerEmail(),
'paymentMethod' => [
'additional_data' => $payment->getAdditionalData(),
'method' => $payment->getMethod(),
'po_number' => $payment->getPoNumber()
]
];

$this->_webApiCall($serviceInfo, $requestData);
}
}
97 changes: 97 additions & 0 deletions ReCaptchaCheckout/Test/Api/PaymentInformationManagementTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\ReCaptchaCheckout\Test\Api;

use Magento\Framework\Webapi\Rest\Request;
use Magento\Integration\Api\CustomerTokenServiceInterface;
use Magento\Quote\Model\Quote;
use Magento\Quote\Model\QuoteFactory;
use Magento\TestFramework\Helper\Bootstrap;
use Magento\TestFramework\TestCase\WebapiAbstract;

/**
* Test that checkout APIs are covered with ReCaptcha
*/
class PaymentInformationManagementTest extends WebapiAbstract
{
private const API_ROUTE = '/V1/carts/mine/payment-information';

/**
* @var QuoteFactory
*/
private $quoteFactory;

/**
* @var CustomerTokenServiceInterface
*/
private $tokenService;

/**
* @inheritDoc
*/
protected function setUp(): void
{
parent::setUp();

$this->_markTestAsRestOnly();
$objectManager = Bootstrap::getObjectManager();
$this->quoteFactory = $objectManager->get(QuoteFactory::class);
$this->tokenService = $objectManager->get(CustomerTokenServiceInterface::class);
}

/**
* @magentoApiDataFixture Magento/Checkout/_files/customer_quote_ready_for_order.php
* @magentoConfigFixture default_store customer/captcha/enable 0
* @magentoConfigFixture base_website recaptcha_frontend/type_invisible/public_key test_public_key
* @magentoConfigFixture base_website recaptcha_frontend/type_invisible/private_key test_private_key
* @magentoConfigFixture base_website recaptcha_frontend/type_for/place_order invisible
*/
public function testRequired(): void
{
$this->expectException(\Throwable::class);
$this->expectExceptionCode(400);
$this->expectExceptionMessage('{"message":"ReCaptcha validation failed, please try again"}');

/** @var Quote $quote */
$quote = $this->quoteFactory->create();
$quote->load('55555555', 'reserved_order_id');
$cartId = $quote->getId();
$payment = $quote->getPayment();
$address = $quote->getBillingAddress();
$addressData = [];
$addressProperties = [
'city', 'company', 'countryId', 'firstname', 'lastname', 'postcode',
'region', 'regionCode', 'regionId', 'saveInAddressBook', 'street', 'telephone', 'email'
];
foreach ($addressProperties as $property) {
$method = 'get' . $property;
$addressData[$property] = $address->$method();
}
$token = $this->tokenService->createCustomerAccessToken('customer@example.com', 'password');

$serviceInfo = [
'rest' => [
'resourcePath' => self::API_ROUTE,
'httpMethod' => Request::HTTP_METHOD_POST,
'token' => $token
],
];
$requestData = [
'cart_id' => $cartId,
'billingAddress' => $addressData,
'email' => $quote->getCustomerEmail(),
'paymentMethod' => [
'additional_data' => $payment->getAdditionalData(),
'method' => $payment->getMethod(),
'po_number' => $payment->getPoNumber()
]
];

$this->_webApiCall($serviceInfo, $requestData);
}
}
7 changes: 6 additions & 1 deletion ReCaptchaCheckout/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
"php": "~7.3.0||~7.4.0",
"magento/framework": "*",
"magento/module-checkout": "*",
"magento/module-re-captcha-ui": "*"
"magento/module-re-captcha-ui": "*",
"magento/module-re-captcha-validation-api": "*",
"magento/module-re-captcha-admin-ui": "*",
"magento/module-re-captcha-frontend-ui": "*",
"magento/module-re-captcha-webapi-api": "*",
"magento/module-re-captcha-webapi-ui": "*"
},
"type": "magento2-module",
"license": "OSL-3.0",
Expand Down
21 changes: 21 additions & 0 deletions ReCaptchaCheckout/etc/adminhtml/system.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="recaptcha_frontend">
<group id="type_for">
<field id="place_order" translate="label" type="select" sortOrder="175" showInDefault="1"
showInWebsite="1" showInStore="0" canRestore="1">
<label>Enable for Checkout/Placing Order</label>
<source_model>Magento\ReCaptchaAdminUi\Model\OptionSource\Type</source_model>
</field>
</group>
</section>
</system>
</config>
17 changes: 17 additions & 0 deletions ReCaptchaCheckout/etc/config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<recaptcha_frontend>
<type_for>
<place_order/>
</type_for>
</recaptcha_frontend>
</default>
</config>
17 changes: 17 additions & 0 deletions ReCaptchaCheckout/etc/di.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\ReCaptchaWebapiApi\Model\CompositeWebapiValidationConfigProvider">
<arguments>
<argument name="providers" xsi:type="array">
<item name="checkout" xsi:type="object">Magento\ReCaptchaCheckout\Model\WebapiConfigProvider</item>
</argument>
</arguments>
</type>
</config>
17 changes: 17 additions & 0 deletions ReCaptchaCheckout/view/frontend/layout/checkout_index_index.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,23 @@
</item>
</item>
</item>
<item name="beforeMethods" xsi:type="array">
<item name="children" xsi:type="array">
<item name="place-order-recaptcha-container" xsi:type="array">
<item name="component" xsi:type="string">uiComponent</item>
<item name="template" xsi:type="string">Magento_ReCaptchaCheckout/payment-recaptcha-container</item>
<item name="displayArea" xsi:type="string">beforeMethods</item>
<item name="children" xsi:type="array">
<item name="place-order-recaptcha" xsi:type="array">
<item name="component" xsi:type="string">Magento_ReCaptchaWebapiUi/js/webapiReCaptcha</item>
<item name="displayArea" xsi:type="string">place-order-recaptcha</item>
<item name="configSource" xsi:type="string">checkoutConfig</item>
<item name="reCaptchaId" xsi:type="string">recaptcha-checkout-place-order</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
Expand Down
Loading

0 comments on commit 5ddbc7c

Please sign in to comment.