Skip to content

Commit c1f5f36

Browse files
authored
Merge pull request #413 from magento-performance/cabpi-315-login-with-inactive-user
CABPI-315: Return correct error message for login with inactive user
2 parents 90d528f + d33a5c6 commit c1f5f36

File tree

4 files changed

+225
-14
lines changed

4 files changed

+225
-14
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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\AdminAdobeIms\Api;
10+
11+
/**
12+
* Declare functionality for user logout from the Adobe IMS account
13+
*
14+
* @api
15+
*/
16+
interface ImsLogOutInterface
17+
{
18+
/**
19+
* LogOut User from Adobe IMS Account
20+
*
21+
* @param string|null $accessToken
22+
* @return bool
23+
*/
24+
public function execute(?string $accessToken = null) : bool;
25+
}

app/code/Magento/AdminAdobeIms/Model/LogOut.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use Magento\AdobeImsApi\Api\FlushUserTokensInterface;
1212
use Magento\AdobeImsApi\Api\GetAccessTokenInterface;
1313
use Magento\AdminAdobeIms\Service\ImsConfig;
14-
use Magento\AdobeImsApi\Api\LogOutInterface;
14+
use Magento\AdminAdobeIms\Api\ImsLogOutInterface;
1515
use Magento\Framework\Exception\AuthorizationException;
1616
use Magento\Framework\Exception\LocalizedException;
1717
use Magento\Framework\HTTP\Client\CurlFactory;
@@ -21,7 +21,7 @@
2121
/**
2222
* Represent functionality for log out users from the Adobe account
2323
*/
24-
class LogOut implements LogOutInterface
24+
class LogOut implements ImsLogOutInterface
2525
{
2626
/**
2727
* Successful result code.
@@ -31,22 +31,22 @@ class LogOut implements LogOutInterface
3131
/**
3232
* @var LoggerInterface
3333
*/
34-
private $logger;
34+
private LoggerInterface $logger;
3535

3636
/**
3737
* @var CurlFactory
3838
*/
39-
private $curlFactory;
39+
private CurlFactory $curlFactory;
4040

4141
/**
4242
* @var GetAccessTokenInterface
4343
*/
44-
private $getAccessToken;
44+
private GetAccessTokenInterface $getAccessToken;
4545

4646
/**
4747
* @var FlushUserTokensInterface
4848
*/
49-
private $flushUserTokens;
49+
private FlushUserTokensInterface $flushUserTokens;
5050
/**
5151
* @var ImsConfig
5252
*/
@@ -83,10 +83,12 @@ public function __construct(
8383
/**
8484
* @inheritDoc
8585
*/
86-
public function execute() : bool
86+
public function execute(?string $accessToken = null) : bool
8787
{
8888
try {
89-
$accessToken = $this->getAccessToken->execute();
89+
if ($accessToken === null) {
90+
$accessToken = $this->getAccessToken->execute();
91+
}
9092

9193
if (empty($accessToken)) {
9294
return true;

app/code/Magento/AdminAdobeIms/Service/AdminLoginProcessService.php

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99

1010
namespace Magento\AdminAdobeIms\Service;
1111

12+
use Exception;
1213
use Magento\AdminAdobeIms\Exception\AdobeImsTokenAuthorizationException;
1314
use Magento\AdminAdobeIms\Model\Auth;
15+
use Magento\AdminAdobeIms\Model\LogOut;
1416
use Magento\AdminAdobeIms\Model\User;
1517
use Magento\AdobeIms\Model\LogIn;
1618
use Magento\AdobeImsApi\Api\Data\TokenResponseInterface;
17-
use Magento\Framework\Exception\AuthenticationException;
18-
use Magento\Framework\Exception\CouldNotSaveException;
1919

2020
class AdminLoginProcessService
2121
{
@@ -32,19 +32,27 @@ class AdminLoginProcessService
3232
*/
3333
private LogIn $logIn;
3434

35+
/**
36+
* @var LogOut
37+
*/
38+
private LogOut $logOut;
39+
3540
/**
3641
* @param User $adminUser
3742
* @param Auth $auth
3843
* @param LogIn $logIn
44+
* @param LogOut $logOut
3945
*/
4046
public function __construct(
4147
User $adminUser,
4248
Auth $auth,
43-
LogIn $logIn
49+
LogIn $logIn,
50+
LogOut $logOut
4451
) {
4552
$this->adminUser = $adminUser;
4653
$this->auth = $auth;
4754
$this->logIn = $logIn;
55+
$this->logOut = $logOut;
4856
}
4957

5058
/**
@@ -54,19 +62,43 @@ public function __construct(
5462
* @param TokenResponseInterface $tokenResponse
5563
* @return void
5664
* @throws AdobeImsTokenAuthorizationException
57-
* @throws CouldNotSaveException|AuthenticationException
5865
*/
5966
public function execute(array $profile, TokenResponseInterface $tokenResponse): void
6067
{
6168
$adminUser = $this->adminUser->loadByEmail($profile['email']);
6269
if (empty($adminUser['user_id'])) {
70+
$this->externalLogout($tokenResponse->getAccessToken());
6371
throw new AdobeImsTokenAuthorizationException(
6472
__('No matching admin user found for Adobe ID.')
6573
);
6674
}
6775

68-
$this->logIn->execute((int)$adminUser['user_id'], $tokenResponse);
76+
try {
77+
$this->logIn->execute((int)$adminUser['user_id'], $tokenResponse);
78+
$this->auth->loginByUsername($adminUser['username']);
79+
} catch (Exception $exception) {
80+
$this->externalLogout($tokenResponse->getAccessToken());
81+
throw new AdobeImsTokenAuthorizationException(
82+
__($exception->getMessage())
83+
);
84+
}
85+
}
6986

70-
$this->auth->loginByUsername($adminUser['username']);
87+
/**
88+
* If log in attempt failed, we should clean the Adobe IMS Session
89+
*
90+
* @param string $accessToken
91+
* @return void
92+
* @throws AdobeImsTokenAuthorizationException
93+
*/
94+
private function externalLogout(string $accessToken): void
95+
{
96+
try {
97+
$this->logOut->execute($accessToken);
98+
} catch (Exception $exception) {
99+
throw new AdobeImsTokenAuthorizationException(
100+
__($exception->getMessage())
101+
);
102+
}
71103
}
72104
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
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\AdminAdobeIms\Test\Unit\Service;
10+
11+
use Exception;
12+
use Magento\AdminAdobeIms\Exception\AdobeImsTokenAuthorizationException;
13+
use Magento\AdminAdobeIms\Model\Auth;
14+
use Magento\AdminAdobeIms\Model\LogOut;
15+
use Magento\AdminAdobeIms\Model\User;
16+
use Magento\AdminAdobeIms\Service\AdminLoginProcessService;
17+
use Magento\AdobeIms\Model\LogIn;
18+
use Magento\AdobeImsApi\Api\Data\TokenResponseInterface;
19+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
20+
use PHPUnit\Framework\TestCase;
21+
22+
class AdminLoginProcessServiceTest extends TestCase
23+
{
24+
private const TEST_EMAIL = '[email protected]';
25+
26+
/**
27+
* @var AdminLoginProcessService
28+
*/
29+
private $loginService;
30+
31+
/**
32+
* @var User
33+
*/
34+
private $user;
35+
36+
/**
37+
* @var Auth
38+
*/
39+
private $auth;
40+
41+
/**
42+
* @var LogIn
43+
*/
44+
private $logIn;
45+
46+
/**
47+
* @var LogOut
48+
*/
49+
private $logOut;
50+
51+
/**
52+
* @var TokenResponseInterface
53+
*/
54+
private $tokenResponse;
55+
56+
protected function setUp(): void
57+
{
58+
$objectManagerHelper = new ObjectManagerHelper($this);
59+
60+
$this->user = $this->createMock(User::class);
61+
$this->auth = $this->createMock(Auth::class);
62+
$this->logIn = $this->createMock(LogIn::class);
63+
$this->logOut = $this->createMock(LogOut::class);
64+
65+
$this->tokenResponse = $this->createMock(TokenResponseInterface::class);
66+
$this->tokenResponse
67+
->method('getAccessToken')
68+
->willReturn('accessToken');
69+
70+
$this->loginService = $objectManagerHelper->getObject(
71+
AdminLoginProcessService::class,
72+
[
73+
'adminUser' => $this->user,
74+
'auth' => $this->auth,
75+
'logIn' => $this->logIn,
76+
'logOut' => $this->logOut,
77+
]
78+
);
79+
}
80+
81+
public function testExceptionWillBeThrownWhenNoUserFound(): void
82+
{
83+
$this->user
84+
->method('loadByEmail')
85+
->willReturn([]);
86+
87+
$this->logOut
88+
->expects($this->once())
89+
->method('execute')
90+
->with('accessToken');
91+
92+
$this->expectException(AdobeImsTokenAuthorizationException::class);
93+
$this->expectExceptionMessage('No matching admin user found for Adobe ID.');
94+
95+
$this->loginService->execute(['email' => self::TEST_EMAIL], $this->tokenResponse);
96+
}
97+
98+
/**
99+
* @return void
100+
* @throws AdobeImsTokenAuthorizationException
101+
*/
102+
public function testExceptionWillBeThrownWhenLoginFails(): void
103+
{
104+
$this->user
105+
->method('loadByEmail')
106+
->willReturn([
107+
'user_id' => '1',
108+
'email' => self::TEST_EMAIL,
109+
]);
110+
111+
$this->logIn
112+
->method('execute')
113+
->willThrowException(new Exception());
114+
115+
$this->logOut
116+
->expects($this->once())
117+
->method('execute')
118+
->with('accessToken');
119+
120+
$this->expectException(AdobeImsTokenAuthorizationException::class);
121+
122+
$this->loginService->execute(['email' => self::TEST_EMAIL], $this->tokenResponse);
123+
}
124+
125+
/**
126+
* @return void
127+
* @throws AdobeImsTokenAuthorizationException
128+
*/
129+
public function testExceptionWillBeThrownWhenAuthenticationFails(): void
130+
{
131+
$this->user
132+
->method('loadByEmail')
133+
->willReturn([
134+
'user_id' => '1',
135+
'username' => 'admin',
136+
'email' => self::TEST_EMAIL,
137+
]);
138+
139+
$this->auth
140+
->method('loginByUsername')
141+
->willThrowException(new Exception());
142+
143+
$this->logOut
144+
->expects($this->once())
145+
->method('execute')
146+
->with('accessToken');
147+
148+
$this->expectException(AdobeImsTokenAuthorizationException::class);
149+
150+
$this->loginService->execute(['email' => self::TEST_EMAIL], $this->tokenResponse);
151+
}
152+
}

0 commit comments

Comments
 (0)