Skip to content

Commit 7db61f1

Browse files
Merge branch '2.4.5-develop' into 2.4.5-develop-2.4-develop-sync-05172022
2 parents f1adf23 + c584e2d commit 7db61f1

File tree

14 files changed

+305
-50
lines changed

14 files changed

+305
-50
lines changed

app/code/Magento/Checkout/Controller/Sidebar/UpdateItemQty.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,25 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Checkout\Controller\Sidebar;
79

810
use Magento\Checkout\Model\Cart\RequestQuantityProcessor;
911
use Magento\Checkout\Model\Sidebar;
1012
use Magento\Framework\App\Action\Action;
1113
use Magento\Framework\App\Action\Context;
14+
use Magento\Framework\App\Action\HttpPostActionInterface;
1215
use Magento\Framework\App\ObjectManager;
1316
use Magento\Framework\App\Response\Http;
1417
use Magento\Framework\Exception\LocalizedException;
1518
use Magento\Framework\Json\Helper\Data;
1619
use Psr\Log\LoggerInterface;
1720

18-
class UpdateItemQty extends Action
21+
/**
22+
* Class used to update item quantity.
23+
*/
24+
class UpdateItemQty extends Action implements HttpPostActionInterface
1925
{
2026
/**
2127
* @var Sidebar
@@ -61,12 +67,18 @@ public function __construct(
6167
}
6268

6369
/**
70+
* Action for Quantity update
71+
*
6472
* @return $this
6573
*/
6674
public function execute()
6775
{
6876
$itemId = (int)$this->getRequest()->getParam('item_id');
69-
$itemQty = $this->getRequest()->getParam('item_qty') * 1;
77+
$itemQty = (int)$this->getRequest()->getParam('item_qty');
78+
79+
if ($itemQty <= 0) {
80+
return $this->jsonResponse(__('Invalid Item Quantity Requested.'));
81+
}
7082
$itemQty = $this->quantityProcessor->prepareQuantity($itemQty);
7183

7284
try {

app/code/Magento/Checkout/Model/DefaultConfigProvider.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
use Magento\Quote\Model\QuoteIdMaskFactory;
3232
use Magento\Store\Model\ScopeInterface;
3333
use Magento\Ui\Component\Form\Element\Multiline;
34+
use Magento\Framework\Escaper;
3435

3536
/**
3637
* Default Config Provider for checkout
@@ -191,6 +192,11 @@ class DefaultConfigProvider implements ConfigProviderInterface
191192
*/
192193
private $configPostProcessor;
193194

195+
/**
196+
* @var Escaper
197+
*/
198+
private $escaper;
199+
194200
/**
195201
* @param CheckoutHelper $checkoutHelper
196202
* @param Session $checkoutSession
@@ -222,6 +228,7 @@ class DefaultConfigProvider implements ConfigProviderInterface
222228
* @param AddressMetadataInterface $addressMetadata
223229
* @param AttributeOptionManagementInterface $attributeOptionManager
224230
* @param CustomerAddressDataProvider|null $customerAddressData
231+
* @param Escaper|null $escaper
225232
* @codeCoverageIgnore
226233
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
227234
*/
@@ -255,7 +262,8 @@ public function __construct(
255262
CaptchaConfigPostProcessorInterface $configPostProcessor,
256263
AddressMetadataInterface $addressMetadata = null,
257264
AttributeOptionManagementInterface $attributeOptionManager = null,
258-
CustomerAddressDataProvider $customerAddressData = null
265+
CustomerAddressDataProvider $customerAddressData = null,
266+
Escaper $escaper = null
259267
) {
260268
$this->checkoutHelper = $checkoutHelper;
261269
$this->checkoutSession = $checkoutSession;
@@ -289,6 +297,7 @@ public function __construct(
289297
$this->customerAddressData = $customerAddressData ?:
290298
ObjectManager::getInstance()->get(CustomerAddressDataProvider::class);
291299
$this->configPostProcessor = $configPostProcessor;
300+
$this->escaper = $escaper ?? ObjectManager::getInstance()->get(Escaper::class);
292301
}
293302

294303
/**
@@ -343,6 +352,7 @@ public function getConfig()
343352
'shipping/shipping_policy/shipping_policy_content',
344353
ScopeInterface::SCOPE_STORE
345354
);
355+
$policyContent = $this->escaper->escapeHtml($policyContent);
346356
$output['shippingPolicy'] = [
347357
'isEnabled' => $this->scopeConfig->isSetFlag(
348358
'shipping/shipping_policy/enable_shipping_policy',

app/code/Magento/Checkout/Test/Unit/Controller/Sidebar/UpdateItemQtyTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
use PHPUnit\Framework\TestCase;
2020
use Psr\Log\LoggerInterface;
2121

22+
/**
23+
* Class used to execute test cases for update item quantity
24+
*/
2225
class UpdateItemQtyTest extends TestCase
2326
{
2427
/**
@@ -244,4 +247,36 @@ public function testExecuteWithException(): void
244247

245248
$this->assertEquals('json represented', $this->updateItemQty->execute());
246249
}
250+
251+
/**
252+
* @return void
253+
*/
254+
public function testExecuteWithInvalidItemQty(): void
255+
{
256+
$error = [
257+
'success' => false,
258+
'error_message' => 'Invalid Item Quantity Requested.'
259+
];
260+
$jsonResult = json_encode($error);
261+
$this->requestMock
262+
->method('getParam')
263+
->withConsecutive(['item_id', null], ['item_qty', null])
264+
->willReturnOnConsecutiveCalls('1', '{{7+2}}');
265+
266+
$this->sidebarMock->expects($this->once())
267+
->method('getResponseData')
268+
->with('Invalid Item Quantity Requested.')
269+
->willReturn($error);
270+
271+
$this->jsonHelperMock->expects($this->once())
272+
->method('jsonEncode')
273+
->with($error)
274+
->willReturn($jsonResult);
275+
276+
$this->responseMock->expects($this->once())
277+
->method('representJson')
278+
->willReturn($jsonResult);
279+
280+
$this->assertEquals($jsonResult, $this->updateItemQty->execute());
281+
}
247282
}

app/code/Magento/Checkout/i18n/en_US.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,4 @@ Payment,Payment
186186
"Show Cross-sell Items in the Shopping Cart","Show Cross-sell Items in the Shopping Cart"
187187
"You added %1 to your <a href=""%2"">shopping cart</a>.","You added %1 to your <a href=""%2"">shopping cart</a>."
188188
"The shipping method is missing. Select the shipping method and try again.","The shipping method is missing. Select the shipping method and try again."
189+
"Invalid Item Quantity Requested.","Invalid Item Quantity Requested."

app/code/Magento/Customer/Controller/Account/Confirmation.php

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Customer\Controller\Account;
79

810
use Magento\Customer\Api\AccountManagementInterface;
@@ -13,22 +15,26 @@
1315
use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
1416
use Magento\Framework\App\Action\Context;
1517
use Magento\Framework\App\ObjectManager;
18+
use Magento\Framework\Controller\Result\Redirect;
19+
use Magento\Framework\Exception\LocalizedException;
20+
use Magento\Framework\Exception\NoSuchEntityException;
1621
use Magento\Framework\Exception\State\InvalidTransitionException;
22+
use Magento\Framework\View\Result\Page;
1723
use Magento\Framework\View\Result\PageFactory;
1824
use Magento\Store\Model\StoreManagerInterface;
1925

2026
/**
21-
* Class Confirmation. Send confirmation link to specified email
27+
* Send confirmation link to specified email
2228
*/
2329
class Confirmation extends AbstractAccount implements HttpGetActionInterface, HttpPostActionInterface
2430
{
2531
/**
26-
* @var \Magento\Store\Model\StoreManagerInterface
32+
* @var StoreManagerInterface
2733
*/
2834
protected $storeManager;
2935

3036
/**
31-
* @var \Magento\Customer\Api\AccountManagementInterface
37+
* @var AccountManagementInterface
3238
*/
3339
protected $customerAccountManagement;
3440

@@ -53,7 +59,7 @@ class Confirmation extends AbstractAccount implements HttpGetActionInterface, Ht
5359
* @param PageFactory $resultPageFactory
5460
* @param StoreManagerInterface $storeManager
5561
* @param AccountManagementInterface $customerAccountManagement
56-
* @param Url $customerUrl
62+
* @param Url|null $customerUrl
5763
*/
5864
public function __construct(
5965
Context $context,
@@ -74,48 +80,52 @@ public function __construct(
7480
/**
7581
* Send confirmation link to specified email
7682
*
77-
* @return \Magento\Framework\Controller\Result\Redirect|\Magento\Framework\View\Result\Page
83+
* @return Redirect|Page
84+
* @throws LocalizedException
7885
*/
7986
public function execute()
8087
{
8188
if ($this->session->isLoggedIn()) {
82-
/** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
83-
$resultRedirect = $this->resultRedirectFactory->create();
84-
$resultRedirect->setPath('*/*/');
85-
return $resultRedirect;
89+
return $this->getRedirect('*/*/');
8690
}
8791

88-
// try to confirm by email
8992
$email = $this->getRequest()->getPost('email');
90-
if ($email) {
91-
/** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
92-
$resultRedirect = $this->resultRedirectFactory->create();
9393

94+
if ($email) {
9495
try {
9596
$this->customerAccountManagement->resendConfirmation(
9697
$email,
9798
$this->storeManager->getStore()->getWebsiteId()
9899
);
99100
$this->messageManager->addSuccessMessage(__('Please check your email for confirmation key.'));
101+
return $this->getRedirect('*/*/index', ['_secure' => true]);
100102
} catch (InvalidTransitionException $e) {
101103
$this->messageManager->addSuccessMessage(__('This email does not require confirmation.'));
102-
} catch (\Exception $e) {
103-
$this->messageManager->addExceptionMessage($e, __('Wrong email.'));
104-
$resultRedirect->setPath('*/*/*', ['email' => $email, '_secure' => true]);
105-
return $resultRedirect;
104+
return $this->getRedirect('*/*/index', ['_secure' => true]);
105+
} catch (NoSuchEntityException $e) {
106+
$this->messageManager->addErrorMessage(__('Wrong email.'));
106107
}
107-
$this->session->setUsername($email);
108-
$resultRedirect->setPath('*/*/index', ['_secure' => true]);
109-
return $resultRedirect;
110108
}
111109

112-
/** @var \Magento\Framework\View\Result\Page $resultPage */
113110
$resultPage = $this->resultPageFactory->create();
114-
$resultPage->getLayout()->getBlock('accountConfirmation')->setEmail(
115-
$this->getRequest()->getParam('email', $email)
116-
)->setLoginUrl(
117-
$this->customerUrl->getLoginUrl()
118-
);
111+
$resultPage->getLayout()->getBlock('accountConfirmation')
112+
->setEmail($email)
113+
->setLoginUrl($this->customerUrl->getLoginUrl());
119114
return $resultPage;
120115
}
116+
117+
/**
118+
* Returns redirect object
119+
*
120+
* @param string $path
121+
* @param array $params
122+
* @return Redirect
123+
*/
124+
private function getRedirect(string $path, array $params = []): Redirect
125+
{
126+
$resultRedirect = $this->resultRedirectFactory->create();
127+
$resultRedirect->setPath($path, $params);
128+
129+
return $resultRedirect;
130+
}
121131
}

app/code/Magento/Customer/Model/Plugin/UpdateCustomer.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use Magento\Framework\Webapi\Rest\Request as RestRequest;
1212
use Magento\Customer\Api\Data\CustomerInterface;
1313
use Magento\Customer\Api\CustomerRepositoryInterface;
14+
use Magento\Authorization\Model\UserContextInterface;
15+
use Magento\Framework\App\ObjectManager;
1416

1517
/**
1618
* Update customer by id from request param
@@ -22,12 +24,19 @@ class UpdateCustomer
2224
*/
2325
private $request;
2426

27+
/**
28+
* @var UserContextInterface
29+
*/
30+
private $userContext;
31+
2532
/**
2633
* @param RestRequest $request
34+
* @param UserContextInterface|null $userContext
2735
*/
28-
public function __construct(RestRequest $request)
36+
public function __construct(RestRequest $request, ?UserContextInterface $userContext = null)
2937
{
3038
$this->request = $request;
39+
$this->userContext = $userContext ?? ObjectManager::getInstance()->get(UserContextInterface::class);
3140
}
3241

3342
/**
@@ -43,10 +52,14 @@ public function beforeSave(
4352
CustomerInterface $customer,
4453
?string $passwordHash = null
4554
): array {
46-
$customerId = $this->request->getParam('customerId');
55+
$customerSessionId = $this->userContext->getUserType() === $this->userContext::USER_TYPE_CUSTOMER ?
56+
(int)$this->userContext->getUserId() : 0;
57+
$customerId = (int)$this->request->getParam('customerId');
4758
$bodyParams = $this->request->getBodyParams();
4859
if (!isset($bodyParams['customer']['Id']) && $customerId) {
49-
$customer = $this->getUpdatedCustomer($customerRepository->getById($customerId), $customer);
60+
if ($customerId === $customerSessionId || $customerSessionId === 0) {
61+
$customer = $this->getUpdatedCustomer($customerRepository->getById($customerId), $customer);
62+
}
5063
}
5164

5265
return [$customer, $passwordHash];
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
namespace Magento\Quote\Plugin\Webapi\Controller\Rest;
8+
9+
use Magento\Webapi\Controller\Rest\ParamsOverrider;
10+
11+
/**
12+
* Validates Quote Data
13+
*/
14+
class ValidateQuoteData
15+
{
16+
private const QUOTE_KEY = 'quote';
17+
18+
/**
19+
* Before Overriding to validate data
20+
*
21+
* @param ParamsOverrider $subject
22+
* @param array $inputData
23+
* @param array $parameters
24+
* @return array[]
25+
*
26+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
27+
*/
28+
29+
public function beforeOverride(ParamsOverrider $subject, array $inputData, array $parameters): array
30+
{
31+
if (isset($inputData[self:: QUOTE_KEY])) {
32+
$inputData[self:: QUOTE_KEY] = $this->validateInputData($inputData[self:: QUOTE_KEY]);
33+
};
34+
return [$inputData, $parameters];
35+
}
36+
37+
/**
38+
* Validates InputData
39+
*
40+
* @param array $inputData
41+
* @return array
42+
*/
43+
private function validateInputData(array $inputData): array
44+
{
45+
$result = [];
46+
47+
$data = array_filter($inputData, function ($k) use (&$result) {
48+
$key = is_string($k) ? strtolower($k) : $k;
49+
return !isset($result[$key]) && ($result[$key] = true);
50+
}, ARRAY_FILTER_USE_KEY);
51+
52+
return array_map(function ($value) {
53+
return is_array($value) ? $this->validateInputData($value) : $value;
54+
}, $data);
55+
}
56+
}

0 commit comments

Comments
 (0)