Skip to content

Commit 3ee4db8

Browse files
Merge remote-tracking branch 'remotes/github/2.3-develop' into EPAM-PR-27
2 parents c2d527b + 3a42052 commit 3ee4db8

File tree

141 files changed

+1786
-508
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

141 files changed

+1786
-508
lines changed

README.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,17 @@ Magento is thankful for any contribution that can improve our code base, documen
3939
<img src="https://raw.githubusercontent.com/wiki/magento/magento2/images/contributors.png"/>
4040
</a>
4141

42-
<h3>Labels applied by the Magento team</h3>
43-
We apply labels to public Pull Requests and Issues to help other participants retrieve additional information about current progress, component assignments, Magento release lines, and much more.
44-
Please review the <a href="https://devdocs.magento.com/guides/v2.3/contributor-guide/contributing.html#labels">Code Contributions guide</a> for detailed information on labels used in Magento 2 repositories.
42+
### Labels applied by the Magento team
43+
We apply labels to public Pull Requests and Issues to help other participants retrieve additional information about current progress, component assignments, Magento release lines, and much more.
44+
Please review the [Code Contributions guide](https://devdocs.magento.com/guides/v2.3/contributor-guide/contributing.html#labels) for detailed information on labels used in Magento 2 repositories.
4545

46-
<h2>Reporting security issues</h2>
46+
## Reporting security issues
4747

48-
To report security vulnerabilities in Magento software or web sites, please create a Bugcrowd researcher account <a href="https://bugcrowd.com/magento">there</a> to submit and follow-up your issue. Learn more about reporting security issues <a href="https://magento.com/security/reporting-magento-security-issue">here</a>.
48+
To report security vulnerabilities in Magento software or web sites, please create a Bugcrowd researcher account [there](https://bugcrowd.com/magento) to submit and follow-up your issue. Learn more about reporting security issues [here](https://magento.com/security/reporting-magento-security-issue).
4949

50-
Stay up-to-date on the latest security news and patches for Magento by signing up for <a href="https://magento.com/security/sign-up">Security Alert Notifications</a>.
50+
Stay up-to-date on the latest security news and patches for Magento by signing up for [Security Alert Notifications](https://magento.com/security/sign-up).
5151

52-
<h2>License</h2>
52+
## License
5353

5454
Each Magento source file included in this distribution is licensed under OSL 3.0 or the Magento Enterprise Edition (MEE) license.
5555

@@ -59,3 +59,13 @@ Please see [LICENSE.txt](https://github.com/magento/magento2/blob/2.3-develop/LI
5959
Subject to Licensee's payment of fees and compliance with the terms and conditions of the MEE License, the MEE License supersedes the OSL 3.0 license for each source file.
6060
Please see LICENSE_EE.txt for the full text of the MEE License or visit https://magento.com/legal/terms/enterprise.
6161

62+
## Community Engineering Slack
63+
64+
To connect with Magento and the Community, join us on the [Magento Community Engineering Slack](https://magentocommeng.slack.com). If you are interested in joining Slack, or a specific channel, send us request at [engcom@adobe.com](mailto:engcom@adobe.com) or [self signup](https://tinyurl.com/engcom-slack).
65+
66+
67+
We have channels for each project. These channels are recommended for new members:
68+
69+
- [general](https://magentocommeng.slack.com/messages/C4YS78WE6): Open chat for introductions and Magento 2 questions
70+
- [github](https://magentocommeng.slack.com/messages/C7KB93M32): Support for GitHub issues, pull requests, and processes
71+
- [public-backlog](https://magentocommeng.slack.com/messages/CCV3J3RV5): Discussions of the Magento 2 backlog

app/code/Magento/AdminNotification/Model/ResourceModel/Inbox.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
namespace Magento\AdminNotification\Model\ResourceModel;
77

88
/**
9+
* Inbox resource model
10+
*
911
* @api
1012
* @since 100.0.2
1113
*/
@@ -77,8 +79,7 @@ public function getNoticeStatus(\Magento\AdminNotification\Model\Inbox $object)
7779
'is_read=?',
7880
0
7981
);
80-
$return = $connection->fetchPairs($select);
81-
return $return;
82+
return $connection->fetchPairs($select);
8283
}
8384

8485
/**
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Captcha\CustomerData;
10+
11+
use Magento\Customer\CustomerData\SectionSourceInterface;
12+
13+
/**
14+
* Captcha section
15+
*/
16+
class Captcha extends \Magento\Framework\DataObject implements SectionSourceInterface
17+
{
18+
/**
19+
* @var array
20+
*/
21+
private $formIds;
22+
23+
/**
24+
* @var \Magento\Captcha\Helper\Data
25+
*/
26+
private $helper;
27+
28+
/**
29+
* @param \Magento\Captcha\Helper\Data $helper
30+
* @param array $formIds
31+
* @param array $data
32+
* @codeCoverageIgnore
33+
*/
34+
public function __construct(
35+
\Magento\Captcha\Helper\Data $helper,
36+
array $formIds,
37+
array $data = []
38+
) {
39+
parent::__construct($data);
40+
$this->helper = $helper;
41+
$this->formIds = $formIds;
42+
}
43+
44+
/**
45+
* @inheritdoc
46+
*/
47+
public function getSectionData() :array
48+
{
49+
$data = [];
50+
51+
foreach ($this->formIds as $formId) {
52+
$captchaModel = $this->helper->getCaptcha($formId);
53+
$data[$formId] = [
54+
'isRequired' => $captchaModel->isRequired(),
55+
'timestamp' => time()
56+
];
57+
}
58+
59+
return $data;
60+
}
61+
}

app/code/Magento/Captcha/Model/Checkout/ConfigProvider.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
*/
66
namespace Magento\Captcha\Model\Checkout;
77

8+
/**
9+
* Configuration provider for Captcha rendering.
10+
*/
811
class ConfigProvider implements \Magento\Checkout\Model\ConfigProviderInterface
912
{
1013
/**
@@ -38,7 +41,7 @@ public function __construct(
3841
}
3942

4043
/**
41-
* {@inheritdoc}
44+
* @inheritdoc
4245
*/
4346
public function getConfig()
4447
{
@@ -49,7 +52,8 @@ public function getConfig()
4952
'imageHeight' => $this->getImageHeight($formId),
5053
'imageSrc' => $this->getImageSrc($formId),
5154
'refreshUrl' => $this->getRefreshUrl(),
52-
'isRequired' => $this->isRequired($formId)
55+
'isRequired' => $this->isRequired($formId),
56+
'timestamp' => time()
5357
];
5458
}
5559
return $config;

app/code/Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,15 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6-
declare(strict_types=1);
76

87
namespace Magento\Captcha\Model\Customer\Plugin;
98

109
use Magento\Captcha\Helper\Data as CaptchaHelper;
11-
use Magento\Customer\Controller\Ajax\Login;
12-
use Magento\Framework\Controller\Result\Json;
13-
use Magento\Framework\Controller\Result\JsonFactory;
1410
use Magento\Framework\Session\SessionManagerInterface;
11+
use Magento\Framework\Controller\Result\JsonFactory;
1512

1613
/**
17-
* The plugin for ajax login controller.
14+
* Around plugin for login action.
1815
*/
1916
class AjaxLogin
2017
{
@@ -67,14 +64,16 @@ public function __construct(
6764
}
6865

6966
/**
70-
* Validates captcha during request execution.
67+
* Check captcha data on login action.
7168
*
72-
* @param Login $subject
69+
* @param \Magento\Customer\Controller\Ajax\Login $subject
7370
* @param \Closure $proceed
7471
* @return $this
72+
* @SuppressWarnings(PHPMD.NPathComplexity)
73+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
7574
*/
7675
public function aroundExecute(
77-
Login $subject,
76+
\Magento\Customer\Controller\Ajax\Login $subject,
7877
\Closure $proceed
7978
) {
8079
$captchaFormIdField = 'captcha_form_id';
@@ -99,31 +98,28 @@ public function aroundExecute(
9998
foreach ($this->formIds as $formId) {
10099
if ($formId === $loginFormId) {
101100
$captchaModel = $this->helper->getCaptcha($formId);
102-
103101
if ($captchaModel->isRequired($username)) {
104102
if (!$captchaModel->isCorrect($captchaString)) {
105103
$this->sessionManager->setUsername($username);
106104
$captchaModel->logAttempt($username);
107-
return $this->returnJsonError(__('Incorrect CAPTCHA'), true);
105+
return $this->returnJsonError(__('Incorrect CAPTCHA'));
108106
}
109107
}
110-
111108
$captchaModel->logAttempt($username);
112109
}
113110
}
114111
return $proceed();
115112
}
116113

117114
/**
118-
* Gets Json response.
115+
* Format JSON response.
119116
*
120117
* @param \Magento\Framework\Phrase $phrase
121-
* @param bool $isCaptchaRequired
122-
* @return Json
118+
* @return \Magento\Framework\Controller\Result\Json
123119
*/
124-
private function returnJsonError(\Magento\Framework\Phrase $phrase, bool $isCaptchaRequired = false): Json
120+
private function returnJsonError(\Magento\Framework\Phrase $phrase): \Magento\Framework\Controller\Result\Json
125121
{
126122
$resultJson = $this->resultJsonFactory->create();
127-
return $resultJson->setData(['errors' => true, 'message' => $phrase, 'captcha' => $isCaptchaRequired]);
123+
return $resultJson->setData(['errors' => true, 'message' => $phrase]);
128124
}
129125
}

app/code/Magento/Captcha/Model/DefaultModel.php

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ class DefaultModel extends \Zend\Captcha\Image implements \Magento\Captcha\Model
7878
*/
7979
protected $session;
8080

81+
/**
82+
* @var string
83+
*/
84+
private $words;
85+
8186
/**
8287
* @param \Magento\Framework\Session\SessionManagerInterface $session
8388
* @param \Magento\Captcha\Helper\Data $captchaData
@@ -311,18 +316,18 @@ public function getImgUrl()
311316
*/
312317
public function isCorrect($word)
313318
{
314-
$storedWord = $this->getWord();
319+
$storedWords = $this->getWords();
315320
$this->clearWord();
316321

317-
if (!$word || !$storedWord) {
322+
if (!$word || !$storedWords) {
318323
return false;
319324
}
320325

321326
if (!$this->isCaseSensitive()) {
322-
$storedWord = strtolower($storedWord);
327+
$storedWords = strtolower($storedWords);
323328
$word = strtolower($word);
324329
}
325-
return $word === $storedWord;
330+
return in_array($word, explode(',', $storedWords));
326331
}
327332

328333
/**
@@ -481,14 +486,25 @@ private function getTargetForms()
481486
/**
482487
* Get captcha word
483488
*
484-
* @return string
489+
* @return string|null
485490
*/
486491
public function getWord()
487492
{
488493
$sessionData = $this->session->getData($this->getFormIdKey(self::SESSION_WORD));
489494
return time() < $sessionData['expires'] ? $sessionData['data'] : null;
490495
}
491496

497+
/**
498+
* Get captcha words
499+
*
500+
* @return string|null
501+
*/
502+
private function getWords()
503+
{
504+
$sessionData = $this->session->getData($this->getFormIdKey(self::SESSION_WORD));
505+
return time() < $sessionData['expires'] ? $sessionData['words'] : null;
506+
}
507+
492508
/**
493509
* Set captcha word
494510
*
@@ -498,9 +514,10 @@ public function getWord()
498514
*/
499515
protected function setWord($word)
500516
{
517+
$this->words = $this->words ? $this->words . ',' . $word : $word;
501518
$this->session->setData(
502519
$this->getFormIdKey(self::SESSION_WORD),
503-
['data' => $word, 'expires' => time() + $this->getTimeout()]
520+
['data' => $word, 'words' => $this->words, 'expires' => time() + $this->getTimeout()]
504521
);
505522
$this->word = $word;
506523
return $this;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
11+
<section name="StorefrontCustomerSignInPopupFormSection">
12+
<element name="captchaField" type="input" selector="#captcha_user_login"/>
13+
<element name="captchaImg" type="block" selector=".captcha-img"/>
14+
<element name="captchaReload" type="block" selector=".captcha-reload"/>
15+
</section>
16+
</sections>

app/code/Magento/Captcha/Test/Mftf/Test/CaptchaFormsDisplayingTest.xml

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,52 @@
6464
<!--Roll back configuration-->
6565
<scrollToTopOfPage stepKey="ScrollToTop"/>
6666
<click selector="{{CaptchaFormsDisplayingSection.captcha}}" stepKey="ClickToCloseCaptcha"/>
67-
67+
</test>
68+
<test name="CaptchaWithDisabledGuestCheckout">
69+
<annotations>
70+
<features value="Captcha"/>
71+
<stories value="MC-5602 - CAPTCHA doesn't appear in login popup after refreshing page."/>
72+
<title value="Captcha is displaying on login form with disabled guest checkout"/>
73+
<description value="Captcha is displaying on login form with disabled guest checkout"/>
74+
<severity value="MAJOR"/>
75+
<testCaseId value="MAGETWO-96691"/>
76+
<group value="captcha"/>
77+
</annotations>
78+
<before>
79+
<magentoCLI command="config:set checkout/options/guest_checkout 0" stepKey="disableGuestCheckout"/>
80+
<magentoCLI command="config:set customer/captcha/failed_attempts_login 1" stepKey="decreaseLoginAttempt"/>
81+
<createData entity="ApiCategory" stepKey="createCategory"/>
82+
<createData entity="ApiSimpleProduct" stepKey="createSimpleProduct">
83+
<requiredEntity createDataKey="createCategory"/>
84+
</createData>
85+
</before>
86+
<after>
87+
<magentoCLI command="config:set checkout/options/guest_checkout 1" stepKey="enableGuestCheckout"/>
88+
<magentoCLI command="config:set customer/captcha/failed_attempts_login 3" stepKey="increaseLoginAttempt"/>
89+
<deleteData createDataKey="createCategory" stepKey="deleteCategory"/>
90+
<deleteData createDataKey="createSimpleProduct" stepKey="deleteSimpleProduct1"/>
91+
</after>
92+
<amOnPage url="{{StorefrontProductPage.url($$createSimpleProduct.sku$$)}}" stepKey="openProductPage"/>
93+
<waitForPageLoad stepKey="waitForPageLoad"/>
94+
<click selector="{{StorefrontProductActionSection.addToCart}}" stepKey="addToCart" />
95+
<waitForText userInput="You added $$createSimpleProduct.name$$ to your shopping cart." stepKey="waitForText"/>
96+
<click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickCart"/>
97+
<click selector="{{StorefrontMinicartSection.goToCheckout}}" stepKey="goToCheckout"/>
98+
<waitForElementVisible selector="{{StorefrontCustomerSignInPopupFormSection.email}}" stepKey="waitEmailFieldVisible"/>
99+
<fillField selector="{{StorefrontCustomerSignInPopupFormSection.email}}" userInput="{{Simple_US_Customer.email}}" stepKey="fillCustomerEmail"/>
100+
<fillField selector="{{StorefrontCustomerSignInPopupFormSection.password}}" userInput="incorrectPassword" stepKey="fillIncorrectCustomerPassword"/>
101+
<click selector="{{StorefrontCustomerSignInPopupFormSection.signIn}}" stepKey="clickSignIn"/>
102+
<waitForElementVisible selector="{{StorefrontCustomerSignInPopupFormSection.errorMessage}}" stepKey="seeErrorMessage"/>
103+
<waitForElementVisible selector="{{StorefrontCustomerSignInPopupFormSection.captchaField}}" stepKey="seeCaptchaField"/>
104+
<waitForElementVisible selector="{{StorefrontCustomerSignInPopupFormSection.captchaImg}}" stepKey="seeCaptchaImage"/>
105+
<waitForElementVisible selector="{{StorefrontCustomerSignInPopupFormSection.captchaReload}}" stepKey="seeCaptchaReloadButton"/>
106+
<reloadPage stepKey="refreshPage"/>
107+
<waitForPageLoad stepKey="waitForPageLoad2"/>
108+
<click selector="{{StorefrontMinicartSection.showCart}}" stepKey="clickCart2"/>
109+
<click selector="{{StorefrontMinicartSection.goToCheckout}}" stepKey="goToCheckout2"/>
110+
<waitForElementVisible selector="{{StorefrontCustomerSignInPopupFormSection.email}}" stepKey="waitEmailFieldVisible2"/>
111+
<waitForElementVisible selector="{{StorefrontCustomerSignInPopupFormSection.captchaField}}" stepKey="seeCaptchaField2"/>
112+
<waitForElementVisible selector="{{StorefrontCustomerSignInPopupFormSection.captchaImg}}" stepKey="seeCaptchaImage2"/>
113+
<waitForElementVisible selector="{{StorefrontCustomerSignInPopupFormSection.captchaReload}}" stepKey="seeCaptchaReloadButton2"/>
68114
</test>
69115
</tests>

app/code/Magento/Captcha/Test/Unit/Model/Checkout/ConfigProviderTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public function testGetConfig($isRequired, $captchaGenerations, $expectedConfig)
7777
->will($this->returnValue('https://magento.com/captcha'));
7878

7979
$config = $this->model->getConfig();
80+
unset($config['captcha'][$this->formId]['timestamp']);
8081
$this->assertEquals($config, $expectedConfig);
8182
}
8283

app/code/Magento/Captcha/Test/Unit/Model/Customer/Plugin/AjaxLoginTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public function testAroundExecuteIncorrectCaptcha()
158158
$this->resultJsonMock
159159
->expects($this->once())
160160
->method('setData')
161-
->with(['errors' => true, 'message' => __('Incorrect CAPTCHA'), 'captcha' => true])
161+
->with(['errors' => true, 'message' => __('Incorrect CAPTCHA')])
162162
->will($this->returnSelf());
163163

164164
$closure = function () {

0 commit comments

Comments
 (0)