Skip to content

Commit 484cfcf

Browse files
Merge pull request #2832 from magento-qwerty/2.1.15-bugfixes-120718
Fixed issues: - MAGETWO-83492: [Backport for 2.1.x] Reset Password - MAGETWO-92196: [Backport for 2.1.x] Mass Action Wrong Requests - MAGETWO-92721: [Backport for 2.1.x] E-mail admin users when a new administrator is created.
2 parents 298969b + 19b6d8a commit 484cfcf

File tree

23 files changed

+354
-4079
lines changed

23 files changed

+354
-4079
lines changed

app/code/Magento/Customer/Api/AccountManagementInterface.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
namespace Magento\Customer\Api;
99

10+
use Magento\Framework\Exception\InputException;
11+
1012
/**
1113
* Interface for managing customers accounts.
1214
* @api
@@ -143,19 +145,24 @@ public function initiatePasswordReset($email, $template, $websiteId = null);
143145
/**
144146
* Reset customer password.
145147
*
146-
* @param string $email
148+
* @param string $email If empty value given then the customer
149+
* will be matched by the RP token.
147150
* @param string $resetToken
148151
* @param string $newPassword
152+
*
149153
* @return bool true on success
150154
* @throws \Magento\Framework\Exception\LocalizedException
155+
* @throws InputException
151156
*/
152157
public function resetPassword($email, $resetToken, $newPassword);
153158

154159
/**
155160
* Check if password reset token is valid.
156161
*
157-
* @param int $customerId
162+
* @param int $customerId If 0 is given then a customer
163+
* will be matched by the RP token.
158164
* @param string $resetPasswordLinkToken
165+
*
159166
* @return bool True if the token is valid
160167
* @throws \Magento\Framework\Exception\State\InputMismatchException If token is mismatched
161168
* @throws \Magento\Framework\Exception\State\ExpiredException If token is expired

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,27 +52,30 @@ public function __construct(
5252
public function execute()
5353
{
5454
$resetPasswordToken = (string)$this->getRequest()->getParam('token');
55-
$customerId = (int)$this->getRequest()->getParam('id');
56-
$isDirectLink = $resetPasswordToken != '' && $customerId != 0;
55+
$isDirectLink = $resetPasswordToken != '';
5756
if (!$isDirectLink) {
5857
$resetPasswordToken = (string)$this->session->getRpToken();
59-
$customerId = (int)$this->session->getRpCustomerId();
6058
}
6159

6260
try {
63-
$this->accountManagement->validateResetPasswordLinkToken($customerId, $resetPasswordToken);
61+
$this->accountManagement->validateResetPasswordLinkToken(
62+
0,
63+
$resetPasswordToken
64+
);
6465

6566
if ($isDirectLink) {
6667
$this->session->setRpToken($resetPasswordToken);
67-
$this->session->setRpCustomerId($customerId);
6868
$resultRedirect = $this->resultRedirectFactory->create();
6969
$resultRedirect->setPath('*/*/createpassword');
70+
7071
return $resultRedirect;
7172
} else {
7273
/** @var \Magento\Framework\View\Result\Page $resultPage */
7374
$resultPage = $this->resultPageFactory->create();
74-
$resultPage->getLayout()->getBlock('resetPassword')->setCustomerId($customerId)
75+
$resultPage->getLayout()
76+
->getBlock('resetPassword')
7577
->setResetPasswordLinkToken($resetPasswordToken);
78+
7679
return $resultPage;
7780
}
7881
} catch (\Exception $exception) {

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

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,26 +55,33 @@ public function execute()
5555
/** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
5656
$resultRedirect = $this->resultRedirectFactory->create();
5757
$resetPasswordToken = (string)$this->getRequest()->getQuery('token');
58-
$customerId = (int)$this->getRequest()->getQuery('id');
5958
$password = (string)$this->getRequest()->getPost('password');
6059
$passwordConfirmation = (string)$this->getRequest()->getPost('password_confirmation');
6160

6261
if ($password !== $passwordConfirmation) {
6362
$this->messageManager->addError(__("New Password and Confirm New Password values didn't match."));
64-
$resultRedirect->setPath('*/*/createPassword', ['id' => $customerId, 'token' => $resetPasswordToken]);
63+
$resultRedirect->setPath(
64+
'*/*/createPassword',
65+
['token' => $resetPasswordToken]
66+
);
6567
return $resultRedirect;
6668
}
6769
if (iconv_strlen($password) <= 0) {
6870
$this->messageManager->addError(__('Please enter a new password.'));
69-
$resultRedirect->setPath('*/*/createPassword', ['id' => $customerId, 'token' => $resetPasswordToken]);
71+
$resultRedirect->setPath(
72+
'*/*/createPassword',
73+
['token' => $resetPasswordToken]
74+
);
7075
return $resultRedirect;
7176
}
7277

7378
try {
74-
$customerEmail = $this->customerRepository->getById($customerId)->getEmail();
75-
$this->accountManagement->resetPassword($customerEmail, $resetPasswordToken, $password);
79+
$this->accountManagement->resetPassword(
80+
'',
81+
$resetPasswordToken,
82+
$password
83+
);
7684
$this->session->unsRpToken();
77-
$this->session->unsRpCustomerId();
7885
$this->messageManager->addSuccess(__('You updated your password.'));
7986
$resultRedirect->setPath('*/*/login');
8087
return $resultRedirect;
@@ -86,7 +93,10 @@ public function execute()
8693
} catch (\Exception $exception) {
8794
$this->messageManager->addError(__('Something went wrong while saving the new password.'));
8895
}
89-
$resultRedirect->setPath('*/*/createPassword', ['id' => $customerId, 'token' => $resetPasswordToken]);
96+
$resultRedirect->setPath(
97+
'*/*/createPassword',
98+
['token' => $resetPasswordToken]
99+
);
90100
return $resultRedirect;
91101
}
92102
}

app/code/Magento/Customer/Model/AccountManagement.php

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Magento\Customer\Model\Metadata\Validator;
1919
use Magento\Eav\Model\Validator\Attribute\Backend;
2020
use Magento\Framework\Api\ExtensibleDataObjectConverter;
21+
use Magento\Framework\Api\SearchCriteriaBuilder;
2122
use Magento\Framework\App\Area;
2223
use Magento\Framework\App\Config\ScopeConfigInterface;
2324
use Magento\Framework\App\ObjectManager;
@@ -39,6 +40,7 @@
3940
use Magento\Framework\Intl\DateTimeFactory;
4041
use Magento\Framework\Mail\Template\TransportBuilder;
4142
use Magento\Framework\Math\Random;
43+
use Magento\Framework\Phrase;
4244
use Magento\Framework\Reflection\DataObjectProcessor;
4345
use Magento\Framework\Registry;
4446
use Magento\Framework\Stdlib\DateTime;
@@ -310,6 +312,11 @@ class AccountManagement implements AccountManagementInterface
310312
*/
311313
private $dateTimeFactory;
312314

315+
/**
316+
* @var SearchCriteriaBuilder
317+
*/
318+
private $searchCriteriaBuilder;
319+
313320
/**
314321
* @param CustomerFactory $customerFactory
315322
* @param ManagerInterface $eventManager
@@ -338,6 +345,7 @@ class AccountManagement implements AccountManagementInterface
338345
* @param SessionManagerInterface|null $sessionManager
339346
* @param SaveHandlerInterface|null $saveHandler
340347
* @param CollectionFactory|null $visitorCollectionFactory
348+
* @param SearchCriteriaBuilder|null $searchCriteriaBuilder
341349
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
342350
*/
343351
public function __construct(
@@ -367,7 +375,8 @@ public function __construct(
367375
DateTimeFactory $dateTimeFactory = null,
368376
SessionManagerInterface $sessionManager = null,
369377
SaveHandlerInterface $saveHandler = null,
370-
CollectionFactory $visitorCollectionFactory = null
378+
CollectionFactory $visitorCollectionFactory = null,
379+
SearchCriteriaBuilder $searchCriteriaBuilder = null
371380
) {
372381
$this->customerFactory = $customerFactory;
373382
$this->eventManager = $eventManager;
@@ -399,6 +408,8 @@ public function __construct(
399408
?: ObjectManager::getInstance()->get(SaveHandlerInterface::class);
400409
$this->visitorCollectionFactory = $visitorCollectionFactory
401410
?: ObjectManager::getInstance()->get(CollectionFactory::class);
411+
$this->searchCriteriaBuilder = $searchCriteriaBuilder
412+
?: ObjectManager::getInstance()->get(SearchCriteriaBuilder::class);
402413
}
403414

404415
/**
@@ -572,12 +583,55 @@ public function initiatePasswordReset($email, $template, $websiteId = null)
572583
return false;
573584
}
574585

586+
/**
587+
* Match a customer by their RP token.
588+
*
589+
* @param string $rpToken
590+
* @throws ExpiredException
591+
* @throws NoSuchEntityException
592+
*
593+
* @return CustomerInterface
594+
*/
595+
private function matchCustomerByRpToken($rpToken)
596+
{
597+
598+
$this->searchCriteriaBuilder->addFilter(
599+
'rp_token',
600+
$rpToken
601+
);
602+
$this->searchCriteriaBuilder->setPageSize(1);
603+
$found = $this->customerRepository->getList(
604+
$this->searchCriteriaBuilder->create()
605+
);
606+
607+
if ($found->getTotalCount() > 1) {
608+
//Failed to generated unique RP token
609+
throw new ExpiredException(
610+
new Phrase('Reset password token expired.')
611+
);
612+
}
613+
if ($found->getTotalCount() === 0) {
614+
//Customer with such token not found.
615+
throw NoSuchEntityException::singleField(
616+
'rp_token',
617+
$rpToken
618+
);
619+
}
620+
621+
//Unique customer found.
622+
return $found->getItems()[0];
623+
}
624+
575625
/**
576626
* {@inheritdoc}
577627
*/
578628
public function resetPassword($email, $resetToken, $newPassword)
579629
{
580-
$customer = $this->customerRepository->get($email);
630+
if (!$email) {
631+
$customer = $this->matchCustomerByRpToken($resetToken);
632+
} else {
633+
$customer = $this->customerRepository->get($email);
634+
}
581635
//Validate Token and new password strength
582636
$this->validateResetPasswordToken($customer->getId(), $resetToken);
583637
$this->checkPasswordStrength($newPassword);
@@ -977,12 +1031,9 @@ public function isCustomerInStore($customerWebsiteId, $storeId)
9771031
private function validateResetPasswordToken($customerId, $resetPasswordLinkToken)
9781032
{
9791033
if (empty($customerId) || $customerId < 0) {
980-
throw new InputException(
981-
__(
982-
'Invalid value of "%value" provided for the %fieldName field.',
983-
['value' => $customerId, 'fieldName' => 'customerId']
984-
)
985-
);
1034+
//Looking for the customer.
1035+
$customerId = $this->matchCustomerByRpToken($resetPasswordLinkToken)
1036+
->getId();
9861037
}
9871038
if (!is_string($resetPasswordLinkToken) || empty($resetPasswordLinkToken)) {
9881039
$params = ['fieldName' => 'resetPasswordLinkToken'];

0 commit comments

Comments
 (0)