Skip to content

Commit 0c1f257

Browse files
Merge pull request #8565 from magento-lynx/lynx-232
[LYNX] generateCustomerToken mutation optimization
2 parents b9f57bd + 9dfe4bd commit 0c1f257

File tree

14 files changed

+643
-595
lines changed

14 files changed

+643
-595
lines changed

app/code/Magento/Catalog/Test/Mftf/Test/StorefrontVerifyCategoryPageNotCachedTest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<!--Login to Admin Panel-->
2323
<actionGroup ref="AdminLoginActionGroup" stepKey="logInAsAdmin"/>
2424
<!-- Create tax rate for CA -->
25-
<createData entity="US_CA_Rate_1" stepKey="createTaxRateCA"/>
25+
<createData entity="TaxRateCalifornia" stepKey="createTaxRateCA"/>
2626
<!-- Create tax rate for TX -->
2727
<createData entity="ThirdTaxRateTexas" stepKey="createTaxRateTX"/>
2828
<!-- Create Tax Rules -->

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: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
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\Model\AccountConfirmation;
23+
use Magento\Customer\Model\AuthenticationInterface;
24+
use Magento\Customer\Model\CustomerFactory;
25+
use Magento\Customer\Model\ResourceModel\CustomerRepository;
26+
use Magento\Framework\Event\ManagerInterface;
27+
use Magento\Framework\Exception\EmailNotConfirmedException;
28+
use Magento\Framework\Exception\InvalidEmailOrPasswordException;
29+
use Magento\Framework\Exception\LocalizedException;
30+
use Magento\Framework\Exception\NoSuchEntityException;
31+
use Magento\Framework\Exception\State\UserLockedException;
32+
33+
/**
34+
* Authenticate customer
35+
*
36+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
37+
*/
38+
class Authenticate
39+
{
40+
/**
41+
* @var CustomerRepository
42+
*/
43+
private CustomerRepository $customerRepository;
44+
45+
/**
46+
* @var CustomerFactory
47+
*/
48+
private CustomerFactory $customerFactory;
49+
50+
/**
51+
* @var AuthenticationInterface
52+
*/
53+
private AuthenticationInterface $authentication;
54+
55+
/**
56+
* @var AccountConfirmation
57+
*/
58+
private AccountConfirmation $accountConfirmation;
59+
60+
/**
61+
* @var ManagerInterface
62+
*/
63+
private ManagerInterface $eventManager;
64+
65+
/**
66+
* @param CustomerRepository $customerRepository
67+
* @param CustomerFactory $customerFactory
68+
* @param AuthenticationInterface $authentication
69+
* @param AccountConfirmation $accountConfirmation
70+
* @param ManagerInterface $eventManager
71+
*/
72+
public function __construct(
73+
CustomerRepository $customerRepository,
74+
CustomerFactory $customerFactory,
75+
AuthenticationInterface $authentication,
76+
AccountConfirmation $accountConfirmation,
77+
ManagerInterface $eventManager
78+
) {
79+
$this->customerRepository = $customerRepository;
80+
$this->customerFactory = $customerFactory;
81+
$this->authentication = $authentication;
82+
$this->accountConfirmation = $accountConfirmation;
83+
$this->eventManager = $eventManager;
84+
}
85+
86+
/**
87+
* Authenticate a customer by username and password
88+
*
89+
* @param string $email
90+
* @param string $password
91+
* @return CustomerInterface
92+
* @throws LocalizedException
93+
*/
94+
public function execute(string $email, string $password): CustomerInterface
95+
{
96+
try {
97+
$customer = $this->customerRepository->get($email);
98+
} catch (NoSuchEntityException $exception) {
99+
throw new InvalidEmailOrPasswordException(__('Invalid login or password.'));
100+
}
101+
102+
$customerId = $customer->getId();
103+
if ($this->authentication->isLocked($customerId)) {
104+
throw new UserLockedException(__('The account is locked.'));
105+
}
106+
try {
107+
$this->authentication->authenticate($customerId, $password);
108+
} catch (InvalidEmailOrPasswordException $exception) {
109+
throw new InvalidEmailOrPasswordException(__('Invalid login or password.'));
110+
}
111+
112+
if ($customer->getConfirmation()
113+
&& ($this->isConfirmationRequired($customer) || $this->isEmailChangedConfirmationRequired($customer))) {
114+
throw new EmailNotConfirmedException(__('This account isn\'t confirmed. Verify and try again.'));
115+
}
116+
117+
$customerModel = $this->customerFactory->create()->updateData($customer);
118+
$this->eventManager->dispatch(
119+
'customer_customer_authenticated',
120+
['model' => $customerModel, 'password' => $password]
121+
);
122+
123+
$this->eventManager->dispatch('customer_data_object_login', ['customer' => $customer]);
124+
125+
return $customer;
126+
}
127+
128+
/**
129+
* Check if accounts confirmation is required in config
130+
*
131+
* @param CustomerInterface $customer
132+
* @return bool
133+
*/
134+
private function isConfirmationRequired($customer)
135+
{
136+
return $this->accountConfirmation->isConfirmationRequired(
137+
$customer->getWebsiteId(),
138+
$customer->getId(),
139+
$customer->getEmail()
140+
);
141+
}
142+
143+
/**
144+
* Checks if account confirmation is required if the email address has been changed
145+
*
146+
* @param CustomerInterface $customer
147+
* @return bool
148+
*/
149+
private function isEmailChangedConfirmationRequired(CustomerInterface $customer): bool
150+
{
151+
return $this->accountConfirmation->isEmailChangedConfirmationRequired(
152+
(int)$customer->getWebsiteId(),
153+
(int)$customer->getId(),
154+
$customer->getEmail()
155+
);
156+
}
157+
}

app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,67 +2072,6 @@ public function testChangePasswordException(): void
20722072
$this->accountManagement->changePassword($email, $currentPassword, $newPassword);
20732073
}
20742074

2075-
/**
2076-
* @return void
2077-
* @throws LocalizedException
2078-
*/
2079-
public function testAuthenticate(): void
2080-
{
2081-
$username = 'login';
2082-
$password = '1234567';
2083-
$passwordHash = '1a2b3f4c';
2084-
2085-
$customerData = $this->getMockBuilder(Customer::class)
2086-
->disableOriginalConstructor()
2087-
->getMock();
2088-
2089-
$customerModel = $this->getMockBuilder(\Magento\Customer\Model\Customer::class)
2090-
->disableOriginalConstructor()
2091-
->getMock();
2092-
$customerModel->expects($this->once())
2093-
->method('updateData')
2094-
->willReturn($customerModel);
2095-
2096-
$this->customerRepository
2097-
->expects($this->once())
2098-
->method('get')
2099-
->with($username)
2100-
->willReturn($customerData);
2101-
2102-
$this->authenticationMock->expects($this->once())
2103-
->method('authenticate');
2104-
2105-
$customerSecure = $this->getMockBuilder(CustomerSecure::class)
2106-
->addMethods(['getPasswordHash'])
2107-
->disableOriginalConstructor()
2108-
->getMock();
2109-
$customerSecure->expects($this->any())
2110-
->method('getPasswordHash')
2111-
->willReturn($passwordHash);
2112-
2113-
$this->customerRegistry->expects($this->any())
2114-
->method('retrieveSecureData')
2115-
->willReturn($customerSecure);
2116-
2117-
$this->customerFactory->expects($this->once())
2118-
->method('create')
2119-
->willReturn($customerModel);
2120-
2121-
$this->manager->expects($this->exactly(2))
2122-
->method('dispatch')
2123-
->withConsecutive(
2124-
[
2125-
'customer_customer_authenticated',
2126-
['model' => $customerModel, 'password' => $password]
2127-
],
2128-
[
2129-
'customer_data_object_login', ['customer' => $customerData]
2130-
]
2131-
);
2132-
2133-
$this->assertEquals($customerData, $this->accountManagement->authenticate($username, $password));
2134-
}
2135-
21362075
/**
21372076
* @param int $isConfirmationRequired
21382077
* @param string|null $confirmation

app/code/Magento/Customer/Test/Unit/Model/SessionTest.php

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -250,51 +250,6 @@ protected function prepareLoginDataMock(int $customerId): MockObject
250250
return $customerDataMock;
251251
}
252252

253-
/**
254-
* @param bool $expectedResult
255-
* @param bool $isCustomerIdValid
256-
* @param bool $isCustomerEmulated
257-
*
258-
* @return void
259-
* @dataProvider getIsLoggedInDataProvider
260-
*/
261-
public function testIsLoggedIn(
262-
bool $expectedResult,
263-
bool $isCustomerIdValid,
264-
bool $isCustomerEmulated
265-
): void {
266-
$customerId = 1;
267-
$this->_storageMock->expects($this->any())->method('getData')->with('customer_id')
268-
->willReturn($customerId);
269-
270-
if ($isCustomerIdValid) {
271-
$this->customerRepositoryMock->expects($this->once())
272-
->method('getById')
273-
->with($customerId);
274-
} else {
275-
$this->customerRepositoryMock->expects($this->once())
276-
->method('getById')
277-
->with($customerId)
278-
->willThrowException(new \Exception('Customer ID is invalid.'));
279-
}
280-
$this->_storageMock->expects($this->any())->method('getIsCustomerEmulated')
281-
->willReturn($isCustomerEmulated);
282-
$this->assertEquals($expectedResult, $this->_model->isLoggedIn());
283-
}
284-
285-
/**
286-
* @return array
287-
*/
288-
public function getIsLoggedInDataProvider(): array
289-
{
290-
return [
291-
['expectedResult' => true, 'isCustomerIdValid' => true, 'isCustomerEmulated' => false],
292-
['expectedResult' => false, 'isCustomerIdValid' => true, 'isCustomerEmulated' => true],
293-
['expectedResult' => false, 'isCustomerIdValid' => false, 'isCustomerEmulated' => false],
294-
['expectedResult' => false, 'isCustomerIdValid' => false, 'isCustomerEmulated' => true]
295-
];
296-
}
297-
298253
/**
299254
* @return void
300255
*/

0 commit comments

Comments
 (0)