Skip to content

Commit 6ee0966

Browse files
committed
LYNX-232: generateCustomerToken mutation optimization
1 parent c22a9db commit 6ee0966

File tree

5 files changed

+284
-93
lines changed

5 files changed

+284
-93
lines changed

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

Lines changed: 11 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Magento\Customer\Api\Data\ValidationResultsInterfaceFactory;
1717
use Magento\Customer\Api\SessionCleanerInterface;
1818
use Magento\Customer\Helper\View as CustomerViewHelper;
19+
use Magento\Customer\Model\AccountManagement\Authenticate;
1920
use Magento\Customer\Model\Config\Share as ConfigShare;
2021
use Magento\Customer\Model\Customer as CustomerModel;
2122
use Magento\Customer\Model\Customer\CredentialsValidator;
@@ -400,6 +401,11 @@ class AccountManagement implements AccountManagementInterface
400401
*/
401402
private CustomerLogger $customerLogger;
402403

404+
/**
405+
* @var Authenticate
406+
*/
407+
private Authenticate $authenticate;
408+
403409
/**
404410
* @param CustomerFactory $customerFactory
405411
* @param ManagerInterface $eventManager
@@ -439,6 +445,7 @@ class AccountManagement implements AccountManagementInterface
439445
* @param AuthenticationInterface|null $authentication
440446
* @param Backend|null $eavValidator
441447
* @param CustomerLogger|null $customerLogger
448+
* @param Authenticate|null $authenticate
442449
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
443450
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
444451
* @SuppressWarnings(PHPMD.NPathComplexity)
@@ -483,7 +490,8 @@ public function __construct(
483490
AuthorizationInterface $authorization = null,
484491
AuthenticationInterface $authentication = null,
485492
Backend $eavValidator = null,
486-
?CustomerLogger $customerLogger = null
493+
CustomerLogger $customerLogger = null,
494+
Authenticate $authenticate = null
487495
) {
488496
$this->customerFactory = $customerFactory;
489497
$this->eventManager = $eventManager;
@@ -527,6 +535,7 @@ public function __construct(
527535
$this->authentication = $authentication ?? $objectManager->get(AuthenticationInterface::class);
528536
$this->eavValidator = $eavValidator ?? $objectManager->get(Backend::class);
529537
$this->customerLogger = $customerLogger ?? $objectManager->get(CustomerLogger::class);
538+
$this->authenticate = $authenticate ?? $objectManager->get(Authenticate::class);
530539
}
531540

532541
/**
@@ -620,51 +629,7 @@ private function activateCustomer($customer, $confirmationKey)
620629
*/
621630
public function authenticate($username, $password)
622631
{
623-
try {
624-
$customer = $this->customerRepository->get($username);
625-
} catch (NoSuchEntityException $e) {
626-
throw new InvalidEmailOrPasswordException(__('Invalid login or password.'));
627-
}
628-
629-
$customerId = $customer->getId();
630-
if ($this->authentication->isLocked($customerId)) {
631-
throw new UserLockedException(__('The account is locked.'));
632-
}
633-
try {
634-
$this->authentication->authenticate($customerId, $password);
635-
} catch (InvalidEmailOrPasswordException $e) {
636-
throw new InvalidEmailOrPasswordException(__('Invalid login or password.'));
637-
}
638-
639-
if ($customer->getConfirmation()
640-
&& ($this->isConfirmationRequired($customer) || $this->isEmailChangedConfirmationRequired($customer))) {
641-
throw new EmailNotConfirmedException(__("This account isn't confirmed. Verify and try again."));
642-
}
643-
644-
$customerModel = $this->customerFactory->create()->updateData($customer);
645-
$this->eventManager->dispatch(
646-
'customer_customer_authenticated',
647-
['model' => $customerModel, 'password' => $password]
648-
);
649-
650-
$this->eventManager->dispatch('customer_data_object_login', ['customer' => $customer]);
651-
652-
return $customer;
653-
}
654-
655-
/**
656-
* Checks if account confirmation is required if the email address has been changed
657-
*
658-
* @param CustomerInterface $customer
659-
* @return bool
660-
*/
661-
private function isEmailChangedConfirmationRequired(CustomerInterface $customer): bool
662-
{
663-
return $this->accountConfirmation->isEmailChangedConfirmationRequired(
664-
(int)$customer->getWebsiteId(),
665-
(int)$customer->getId(),
666-
$customer->getEmail()
667-
);
632+
return $this->authenticate->execute((string) $username, (string) $password);
668633
}
669634

670635
/**
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
<?php
2+
/************************************************************************
3+
*
4+
* Copyright 2023 Adobe
5+
* All Rights Reserved.
6+
*
7+
* NOTICE: All information contained herein is, and remains
8+
* the property of Adobe and its suppliers, if any. The intellectual
9+
* and technical concepts contained herein are proprietary to Adobe
10+
* and its suppliers and are protected by all applicable intellectual
11+
* property laws, including trade secret and copyright laws.
12+
* Dissemination of this information or reproduction of this material
13+
* is strictly forbidden unless prior written permission is obtained
14+
* from Adobe.
15+
* ************************************************************************
16+
*/
17+
declare(strict_types=1);
18+
19+
namespace Magento\Customer\Model\AccountManagement;
20+
21+
use Magento\Customer\Api\Data\CustomerInterface;
22+
use Magento\Customer\Api\Data\CustomerInterfaceFactory;
23+
use Magento\Customer\Model\AccountConfirmation;
24+
use Magento\Customer\Model\AuthenticationInterface;
25+
use Magento\Customer\Model\Customer;
26+
use Magento\Customer\Model\CustomerRegistry;
27+
use Magento\Framework\Api\DataObjectHelper;
28+
use Magento\Framework\Event\ManagerInterface;
29+
use Magento\Framework\Exception\EmailNotConfirmedException;
30+
use Magento\Framework\Exception\InvalidEmailOrPasswordException;
31+
use Magento\Framework\Exception\LocalizedException;
32+
use Magento\Framework\Exception\NoSuchEntityException;
33+
use Magento\Framework\Exception\State\UserLockedException;
34+
35+
/**
36+
* Authenticate customer
37+
*/
38+
class Authenticate
39+
{
40+
/**
41+
* @var CustomerRegistry
42+
*/
43+
private CustomerRegistry $customerRegistry;
44+
45+
/**
46+
* @var DataObjectHelper
47+
*/
48+
private DataObjectHelper $dataObjectHelper;
49+
50+
/**
51+
* @var CustomerInterfaceFactory
52+
*/
53+
private CustomerInterfaceFactory $customerFactory;
54+
55+
/**
56+
* @var AuthenticationInterface
57+
*/
58+
private AuthenticationInterface $authentication;
59+
60+
/**
61+
* @var AccountConfirmation
62+
*/
63+
private AccountConfirmation $accountConfirmation;
64+
65+
/**
66+
* @var ManagerInterface
67+
*/
68+
private ManagerInterface $eventManager;
69+
70+
/**
71+
* @param CustomerRegistry $customerRegistry
72+
* @param DataObjectHelper $dataObjectHelper
73+
* @param CustomerInterfaceFactory $customerFactory
74+
* @param AuthenticationInterface $authentication
75+
* @param AccountConfirmation $accountConfirmation
76+
* @param ManagerInterface $eventManager
77+
*/
78+
public function __construct(
79+
CustomerRegistry $customerRegistry,
80+
DataObjectHelper $dataObjectHelper,
81+
CustomerInterfaceFactory $customerFactory,
82+
AuthenticationInterface $authentication,
83+
AccountConfirmation $accountConfirmation,
84+
ManagerInterface $eventManager
85+
) {
86+
$this->customerRegistry = $customerRegistry;
87+
$this->dataObjectHelper = $dataObjectHelper;
88+
$this->customerFactory = $customerFactory;
89+
$this->authentication = $authentication;
90+
$this->accountConfirmation = $accountConfirmation;
91+
$this->eventManager = $eventManager;
92+
}
93+
94+
/**
95+
* Authenticate a customer by username and password
96+
*
97+
* @param string $email
98+
* @param string $password
99+
* @return CustomerInterface
100+
* @throws LocalizedException
101+
*/
102+
public function execute(string $email, string $password): CustomerInterface
103+
{
104+
try {
105+
$customerModel = $this->customerRegistry->retrieveByEmail($email);
106+
} catch (NoSuchEntityException $exception) {
107+
throw new InvalidEmailOrPasswordException(__('Invalid login or password.'));
108+
}
109+
$customer = $this->getCustomerDataObject($customerModel);
110+
111+
$customerId = $customer->getId();
112+
if ($this->authentication->isLocked($customerId)) {
113+
throw new UserLockedException(__('The account is locked.'));
114+
}
115+
try {
116+
$this->authentication->authenticate($customerId, $password);
117+
} catch (InvalidEmailOrPasswordException $exception) {
118+
throw new InvalidEmailOrPasswordException(__('Invalid login or password.'));
119+
}
120+
121+
if ($customer->getConfirmation()
122+
&& ($this->isConfirmationRequired($customer) || $this->isEmailChangedConfirmationRequired($customer))) {
123+
throw new EmailNotConfirmedException(__('This account isn\'t confirmed. Verify and try again.'));
124+
}
125+
126+
$this->eventManager->dispatch(
127+
'customer_customer_authenticated',
128+
['model' => $customerModel, 'password' => $password]
129+
);
130+
131+
$this->eventManager->dispatch('customer_data_object_login', ['customer' => $customer]);
132+
133+
return $customer;
134+
}
135+
136+
/**
137+
* Convert custom model to DTO
138+
*
139+
* @param Customer $customerModel
140+
* @return CustomerInterface
141+
*/
142+
private function getCustomerDataObject(Customer $customerModel): CustomerInterface
143+
{
144+
$customerDataObject = $this->customerFactory->create();
145+
$this->dataObjectHelper->populateWithArray(
146+
$customerDataObject,
147+
$customerModel->getData(),
148+
CustomerInterface::class
149+
);
150+
$customerDataObject->setId($customerModel->getId());
151+
return $customerDataObject;
152+
}
153+
154+
/**
155+
* Check if accounts confirmation is required in config
156+
*
157+
* @param CustomerInterface $customer
158+
* @return bool
159+
*/
160+
private function isConfirmationRequired($customer)
161+
{
162+
return $this->accountConfirmation->isConfirmationRequired(
163+
$customer->getWebsiteId(),
164+
$customer->getId(),
165+
$customer->getEmail()
166+
);
167+
}
168+
169+
/**
170+
* Checks if account confirmation is required if the email address has been changed
171+
*
172+
* @param CustomerInterface $customer
173+
* @return bool
174+
*/
175+
private function isEmailChangedConfirmationRequired(CustomerInterface $customer): bool
176+
{
177+
return $this->accountConfirmation->isEmailChangedConfirmationRequired(
178+
(int)$customer->getWebsiteId(),
179+
(int)$customer->getId(),
180+
$customer->getEmail()
181+
);
182+
}
183+
}

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ class Session extends \Magento\Framework\Session\SessionManager
107107
*/
108108
private $accountConfirmation;
109109

110+
/**
111+
* @var CustomerRegistry
112+
*/
113+
private $customerRegistry;
114+
110115
/**
111116
* Session constructor.
112117
*
@@ -132,6 +137,7 @@ class Session extends \Magento\Framework\Session\SessionManager
132137
* @param GroupManagementInterface $groupManagement
133138
* @param \Magento\Framework\App\Response\Http $response
134139
* @param AccountConfirmation $accountConfirmation
140+
* @param CustomerRegistry $customerRegistry
135141
* @throws \Magento\Framework\Exception\SessionException
136142
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
137143
*/
@@ -157,7 +163,8 @@ public function __construct(
157163
CustomerRepositoryInterface $customerRepository,
158164
GroupManagementInterface $groupManagement,
159165
\Magento\Framework\App\Response\Http $response,
160-
AccountConfirmation $accountConfirmation = null
166+
AccountConfirmation $accountConfirmation = null,
167+
CustomerRegistry $customerRegistry = null
161168
) {
162169
$this->_coreUrl = $coreUrl;
163170
$this->_customerUrl = $customerUrl;
@@ -173,6 +180,8 @@ public function __construct(
173180
$this->response = $response;
174181
$this->accountConfirmation = $accountConfirmation ?: ObjectManager::getInstance()
175182
->get(AccountConfirmation::class);
183+
$this->customerRegistry = $customerRegistry ?: ObjectManager::getInstance()
184+
->get(CustomerRegistry::class);
176185
parent::__construct(
177186
$request,
178187
$sidResolver,
@@ -431,7 +440,7 @@ public function checkCustomerId($customerId)
431440
}
432441

433442
try {
434-
$this->customerRepository->getById($customerId);
443+
$this->customerRegistry->retrieve($customerId);
435444
$this->_isCustomerIdChecked = $customerId;
436445
return true;
437446
} catch (\Exception $e) {

0 commit comments

Comments
 (0)