Skip to content

Commit 4e11099

Browse files
author
Maksym Novik
committed
Creating Customer without password is directly confirmed #14492
1 parent 211dd25 commit 4e11099

File tree

6 files changed

+247
-74
lines changed

6 files changed

+247
-74
lines changed

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

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@
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;
11+
use Magento\Customer\Model\ForgotPasswordToken\ConfirmCustomerByToken;
912
use Magento\Customer\Model\Session;
1013
use Magento\Framework\App\Action\HttpGetActionInterface;
1114
use Magento\Framework\View\Result\PageFactory;
1215
use Magento\Framework\App\Action\Context;
16+
use Magento\Framework\App\ObjectManager;
1317

1418
/**
1519
* Class CreatePassword
@@ -34,20 +38,30 @@ class CreatePassword extends \Magento\Customer\Controller\AbstractAccount implem
3438
protected $resultPageFactory;
3539

3640
/**
37-
* @param Context $context
38-
* @param Session $customerSession
39-
* @param PageFactory $resultPageFactory
40-
* @param AccountManagementInterface $accountManagement
41+
* @var \Magento\Customer\Model\ForgotPasswordToken\ConfirmCustomerByToken
42+
*/
43+
private $confirmByToken;
44+
45+
/**
46+
* @param \Magento\Framework\App\Action\Context $context
47+
* @param \Magento\Customer\Model\Session $customerSession
48+
* @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
49+
* @param \Magento\Customer\Api\AccountManagementInterface $accountManagement
50+
* @param \Magento\Customer\Model\ForgotPasswordToken\ConfirmCustomerByToken $confirmByToken
4151
*/
4252
public function __construct(
4353
Context $context,
4454
Session $customerSession,
4555
PageFactory $resultPageFactory,
46-
AccountManagementInterface $accountManagement
56+
AccountManagementInterface $accountManagement,
57+
ConfirmCustomerByToken $confirmByToken = null
4758
) {
4859
$this->session = $customerSession;
4960
$this->resultPageFactory = $resultPageFactory;
5061
$this->accountManagement = $accountManagement;
62+
$this->confirmByToken = $confirmByToken
63+
?? ObjectManager::getInstance()->get(ConfirmCustomerByToken::class);
64+
5165
parent::__construct($context);
5266
}
5367

@@ -67,6 +81,8 @@ public function execute()
6781
try {
6882
$this->accountManagement->validateResetPasswordLinkToken(null, $resetPasswordToken);
6983

84+
$this->confirmByToken->execute($resetPasswordToken);
85+
7086
if ($isDirectLink) {
7187
$this->session->setRpToken($resetPasswordToken);
7288
$resultRedirect = $this->resultRedirectFactory->create();
@@ -77,16 +93,17 @@ public function execute()
7793
/** @var \Magento\Framework\View\Result\Page $resultPage */
7894
$resultPage = $this->resultPageFactory->create();
7995
$resultPage->getLayout()
80-
->getBlock('resetPassword')
81-
->setResetPasswordLinkToken($resetPasswordToken);
96+
->getBlock('resetPassword')
97+
->setResetPasswordLinkToken($resetPasswordToken);
8298

8399
return $resultPage;
84100
}
85101
} catch (\Exception $exception) {
86-
$this->messageManager->addError(__('Your password reset link has expired.'));
102+
$this->messageManager->addErrorMessage(__('Your password reset link has expired.'));
87103
/** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
88104
$resultRedirect = $this->resultRedirectFactory->create();
89105
$resultRedirect->setPath('*/*/forgotpassword');
106+
90107
return $resultRedirect;
91108
}
92109
}

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

Lines changed: 44 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Magento\Customer\Model\Config\Share as ConfigShare;
1818
use Magento\Customer\Model\Customer as CustomerModel;
1919
use Magento\Customer\Model\Customer\CredentialsValidator;
20+
use Magento\Customer\Model\ForgotPasswordToken\GetCustomerByToken;
2021
use Magento\Customer\Model\Metadata\Validator;
2122
use Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory;
2223
use Magento\Directory\Model\AllowedCountries;
@@ -44,7 +45,6 @@
4445
use Magento\Framework\Intl\DateTimeFactory;
4546
use Magento\Framework\Mail\Template\TransportBuilder;
4647
use Magento\Framework\Math\Random;
47-
use Magento\Framework\Phrase;
4848
use Magento\Framework\Reflection\DataObjectProcessor;
4949
use Magento\Framework\Registry;
5050
use Magento\Framework\Session\SaveHandlerInterface;
@@ -345,6 +345,11 @@ class AccountManagement implements AccountManagementInterface
345345
*/
346346
private $allowedCountriesReader;
347347

348+
/**
349+
* @var GetCustomerByToken
350+
*/
351+
private $getByToken;
352+
348353
/**
349354
* @param CustomerFactory $customerFactory
350355
* @param ManagerInterface $eventManager
@@ -377,10 +382,12 @@ class AccountManagement implements AccountManagementInterface
377382
* @param CollectionFactory|null $visitorCollectionFactory
378383
* @param SearchCriteriaBuilder|null $searchCriteriaBuilder
379384
* @param AddressRegistry|null $addressRegistry
385+
* @param GetCustomerByToken|null $getByToken
380386
* @param AllowedCountries|null $allowedCountriesReader
387+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
381388
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
382389
* @SuppressWarnings(PHPMD.NPathComplexity)
383-
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
390+
* @SuppressWarnings(PHPMD.LongVariable)
384391
*/
385392
public function __construct(
386393
CustomerFactory $customerFactory,
@@ -414,6 +421,7 @@ public function __construct(
414421
CollectionFactory $visitorCollectionFactory = null,
415422
SearchCriteriaBuilder $searchCriteriaBuilder = null,
416423
AddressRegistry $addressRegistry = null,
424+
GetCustomerByToken $getByToken = null,
417425
AllowedCountries $allowedCountriesReader = null
418426
) {
419427
$this->customerFactory = $customerFactory;
@@ -439,23 +447,26 @@ public function __construct(
439447
$this->customerModel = $customerModel;
440448
$this->objectFactory = $objectFactory;
441449
$this->extensibleDataObjectConverter = $extensibleDataObjectConverter;
450+
$objectManager = ObjectManager::getInstance();
442451
$this->credentialsValidator =
443-
$credentialsValidator ?: ObjectManager::getInstance()->get(CredentialsValidator::class);
444-
$this->dateTimeFactory = $dateTimeFactory ?: ObjectManager::getInstance()->get(DateTimeFactory::class);
445-
$this->accountConfirmation = $accountConfirmation ?: ObjectManager::getInstance()
452+
$credentialsValidator ?: $objectManager->get(CredentialsValidator::class);
453+
$this->dateTimeFactory = $dateTimeFactory ?: $objectManager->get(DateTimeFactory::class);
454+
$this->accountConfirmation = $accountConfirmation ?: $objectManager
446455
->get(AccountConfirmation::class);
447456
$this->sessionManager = $sessionManager
448-
?: ObjectManager::getInstance()->get(SessionManagerInterface::class);
457+
?: $objectManager->get(SessionManagerInterface::class);
449458
$this->saveHandler = $saveHandler
450-
?: ObjectManager::getInstance()->get(SaveHandlerInterface::class);
459+
?: $objectManager->get(SaveHandlerInterface::class);
451460
$this->visitorCollectionFactory = $visitorCollectionFactory
452-
?: ObjectManager::getInstance()->get(CollectionFactory::class);
461+
?: $objectManager->get(CollectionFactory::class);
453462
$this->searchCriteriaBuilder = $searchCriteriaBuilder
454-
?: ObjectManager::getInstance()->get(SearchCriteriaBuilder::class);
463+
?: $objectManager->get(SearchCriteriaBuilder::class);
455464
$this->addressRegistry = $addressRegistry
456-
?: ObjectManager::getInstance()->get(AddressRegistry::class);
465+
?: $objectManager->get(AddressRegistry::class);
466+
$this->getByToken = $getByToken
467+
?: $objectManager->get(GetCustomerByToken::class);
457468
$this->allowedCountriesReader = $allowedCountriesReader
458-
?: ObjectManager::getInstance()->get(AllowedCountries::class);
469+
?: $objectManager->get(AllowedCountries::class);
459470
}
460471

461472
/**
@@ -521,8 +532,11 @@ public function activateById($customerId, $confirmationKey)
521532
* @param \Magento\Customer\Api\Data\CustomerInterface $customer
522533
* @param string $confirmationKey
523534
* @return \Magento\Customer\Api\Data\CustomerInterface
524-
* @throws \Magento\Framework\Exception\State\InvalidTransitionException
525-
* @throws \Magento\Framework\Exception\State\InputMismatchException
535+
* @throws InputException
536+
* @throws InputMismatchException
537+
* @throws InvalidTransitionException
538+
* @throws LocalizedException
539+
* @throws NoSuchEntityException
526540
*/
527541
private function activateCustomer($customer, $confirmationKey)
528542
{
@@ -630,42 +644,6 @@ public function initiatePasswordReset($email, $template, $websiteId = null)
630644
return false;
631645
}
632646

633-
/**
634-
* Match a customer by their RP token.
635-
*
636-
* @param string $rpToken
637-
* @throws ExpiredException
638-
* @throws NoSuchEntityException
639-
* @return CustomerInterface
640-
* @throws LocalizedException
641-
*/
642-
private function matchCustomerByRpToken(string $rpToken): CustomerInterface
643-
{
644-
$this->searchCriteriaBuilder->addFilter(
645-
'rp_token',
646-
$rpToken
647-
);
648-
$this->searchCriteriaBuilder->setPageSize(1);
649-
$found = $this->customerRepository->getList(
650-
$this->searchCriteriaBuilder->create()
651-
);
652-
if ($found->getTotalCount() > 1) {
653-
//Failed to generated unique RP token
654-
throw new ExpiredException(
655-
new Phrase('Reset password token expired.')
656-
);
657-
}
658-
if ($found->getTotalCount() === 0) {
659-
//Customer with such token not found.
660-
throw NoSuchEntityException::singleField(
661-
'rp_token',
662-
$rpToken
663-
);
664-
}
665-
//Unique customer found.
666-
return $found->getItems()[0];
667-
}
668-
669647
/**
670648
* Handle not supported template
671649
*
@@ -691,7 +669,7 @@ private function handleUnknownTemplate($template)
691669
public function resetPassword($email, $resetToken, $newPassword)
692670
{
693671
if (!$email) {
694-
$customer = $this->matchCustomerByRpToken($resetToken);
672+
$customer = $this->getByToken->execute($resetToken);
695673
$email = $customer->getEmail();
696674
} else {
697675
$customer = $this->customerRepository->get($email);
@@ -830,6 +808,8 @@ public function getConfirmationStatus($customerId)
830808

831809
/**
832810
* @inheritdoc
811+
*
812+
* @throws LocalizedException
833813
*/
834814
public function createAccount(CustomerInterface $customer, $password = null, $redirectUrl = '')
835815
{
@@ -852,6 +832,8 @@ public function createAccount(CustomerInterface $customer, $password = null, $re
852832

853833
/**
854834
* @inheritdoc
835+
*
836+
* @throws InputMismatchException
855837
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
856838
* @SuppressWarnings(PHPMD.NPathComplexity)
857839
*/
@@ -987,6 +969,8 @@ protected function sendEmailConfirmation(CustomerInterface $customer, $redirectU
987969

988970
/**
989971
* @inheritdoc
972+
*
973+
* @throws InvalidEmailOrPasswordException
990974
*/
991975
public function changePassword($email, $currentPassword, $newPassword)
992976
{
@@ -1000,6 +984,8 @@ public function changePassword($email, $currentPassword, $newPassword)
1000984

1001985
/**
1002986
* @inheritdoc
987+
*
988+
* @throws InvalidEmailOrPasswordException
1003989
*/
1004990
public function changePasswordById($customerId, $currentPassword, $newPassword)
1005991
{
@@ -1137,12 +1123,14 @@ public function isCustomerInStore($customerWebsiteId, $storeId)
11371123
*
11381124
* @param int $customerId
11391125
* @param string $resetPasswordLinkToken
1126+
*
11401127
* @return bool
1141-
* @throws \Magento\Framework\Exception\State\InputMismatchException If token is mismatched
1142-
* @throws \Magento\Framework\Exception\State\ExpiredException If token is expired
1143-
* @throws \Magento\Framework\Exception\InputException If token or customer id is invalid
1144-
* @throws \Magento\Framework\Exception\NoSuchEntityException If customer doesn't exist
1128+
* @throws ExpiredException If token is expired
1129+
* @throws InputException If token or customer id is invalid
1130+
* @throws InputMismatchException If token is mismatched
11451131
* @throws LocalizedException
1132+
* @throws NoSuchEntityException If customer doesn't exist
1133+
* @SuppressWarnings(PHPMD.LongVariable)
11461134
*/
11471135
private function validateResetPasswordToken($customerId, $resetPasswordLinkToken)
11481136
{
@@ -1157,7 +1145,8 @@ private function validateResetPasswordToken($customerId, $resetPasswordLinkToken
11571145

11581146
if ($customerId === null) {
11591147
//Looking for the customer.
1160-
$customerId = $this->matchCustomerByRpToken($resetPasswordLinkToken)
1148+
$customerId = $this->getByToken
1149+
->execute($resetPasswordLinkToken)
11611150
->getId();
11621151
}
11631152
if (!is_string($resetPasswordLinkToken) || empty($resetPasswordLinkToken)) {
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Customer\Model\ForgotPasswordToken;
9+
10+
use Magento\Customer\Api\CustomerRepositoryInterface;
11+
12+
/**
13+
* Confirm customer by reset password token
14+
*/
15+
class ConfirmCustomerByToken
16+
{
17+
/**
18+
* @var GetCustomerByToken
19+
*/
20+
private $getByToken;
21+
22+
/**
23+
* @var CustomerRepositoryInterface
24+
*/
25+
private $customerRepository;
26+
27+
/**
28+
* ConfirmByToken constructor.
29+
*
30+
* @param GetCustomerByToken $getByToken
31+
* @param CustomerRepositoryInterface $customerRepository
32+
*/
33+
public function __construct(
34+
GetCustomerByToken $getByToken,
35+
CustomerRepositoryInterface $customerRepository
36+
) {
37+
$this->getByToken = $getByToken;
38+
$this->customerRepository = $customerRepository;
39+
}
40+
41+
/**
42+
* Confirm customer account my rp_token
43+
*
44+
* @param string $resetPasswordToken
45+
*
46+
* @return void
47+
* @throws \Magento\Framework\Exception\LocalizedException
48+
*/
49+
public function execute(string $resetPasswordToken): void
50+
{
51+
$customer = $this->getByToken->execute($resetPasswordToken);
52+
if ($customer->getConfirmation()) {
53+
$this->customerRepository->save(
54+
$customer->setConfirmation(null)
55+
);
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)