Skip to content

Commit e55428c

Browse files
committed
OXDEV-9078 Move shop login to the infrastructure layer
1 parent 50067a5 commit e55428c

7 files changed

Lines changed: 105 additions & 20 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/**
4+
* Copyright © OXID eSales AG. All rights reserved.
5+
* See LICENSE file for license details.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Infrastructure\Service;
11+
12+
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Infrastructure\Factory\UserModelFactoryInterface;
13+
14+
class UserLoginAdapter implements UserLoginAdapterInterface
15+
{
16+
public function __construct(
17+
private UserModelFactoryInterface $userFactory,
18+
) {
19+
}
20+
21+
public function loginUser(string $userId): void
22+
{
23+
$user = $this->userFactory->create();
24+
$user->load($userId);
25+
/** @phpstan-ignore argument.type (password is null because user already authenticated to come here) */
26+
$user->login($user->getFieldData('oxusername'), null, false);
27+
}
28+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
/**
4+
* Copyright © OXID eSales AG. All rights reserved.
5+
* See LICENSE file for license details.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Infrastructure\Service;
11+
12+
interface UserLoginAdapterInterface
13+
{
14+
public function loginUser(string $userId): void;
15+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
services:
2+
_defaults:
3+
autowire: true
4+
public: false
5+
6+
OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Infrastructure\Service\UserLoginAdapterInterface:
7+
class: OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Infrastructure\Service\UserLoginAdapter

src/Authentication/TwoFactorAuth/Infrastructure/services.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ imports:
22
- { resource: Factory/services.yaml }
33
- { resource: Provider/services.yaml }
44
- { resource: Repository/services.yaml }
5+
- { resource: Service/services.yaml }

src/Authentication/TwoFactorAuth/Service/TwoFAUserService.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
use OxidEsales\Eshop\Core\Utils;
1313
use OxidEsales\EshopCommunity\Internal\Framework\Session\SessionInterface;
1414
use OxidEsales\SecurityModule\Authentication\Service\InternalRedirectServiceInterface;
15-
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Infrastructure\Factory\UserModelFactoryInterface;
15+
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Infrastructure\Service\UserLoginAdapterInterface;
1616
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Settings\TwoFASettingsInterface;
1717

1818
/**
@@ -27,7 +27,7 @@ public function __construct(
2727
private TwoFASettingsInterface $settings,
2828
private Utils $utils,
2929
private SessionInterface $session,
30-
private UserModelFactoryInterface $userFactory,
30+
private UserLoginAdapterInterface $loginAdapter,
3131
private InternalRedirectServiceInterface $redirectService,
3232
) {
3333
}
@@ -48,12 +48,7 @@ public function loginUser(string $userId): void
4848
{
4949
$this->session->remove(self::USER_SESSION_KEY);
5050

51-
// todo-high: looks like it can go to the infrastructure layer
52-
$user = $this->userFactory->create();
53-
$user->load($userId);
54-
55-
/** @phpstan-ignore argument.type (password is null because user already authenticated to come here) */
56-
$user->login($user->getFieldData('oxusername'), null, false);
51+
$this->loginAdapter->loginUser($userId);
5752

5853
$this->utils->redirect($this->redirectService->getRedirectUrl(), false);
5954
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/**
4+
* Copyright © OXID eSales AG. All rights reserved.
5+
* See LICENSE file for license details.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace OxidEsales\SecurityModule\Tests\Unit\Authentication\TwoFactorAuth\Infrastructure\Service;
11+
12+
use OxidEsales\Eshop\Application\Model\User;
13+
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Infrastructure\Factory\UserModelFactoryInterface;
14+
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Infrastructure\Service\UserLoginAdapter;
15+
use PHPUnit\Framework\Attributes\Test;
16+
use PHPUnit\Framework\TestCase;
17+
18+
class UserLoginAdapterTest extends TestCase
19+
{
20+
#[Test]
21+
public function loginUserLoadsAndLoginsUser(): void
22+
{
23+
$userSpy = $this->createMock(User::class);
24+
$userSpy->expects($this->once())->method('load')->with($userId = uniqid());
25+
$userSpy->method('getFieldData')->with('oxusername')->willReturn($username = uniqid());
26+
$userSpy->expects($this->once())->method('login')->with($username, null, false);
27+
28+
$userFactoryStub = $this->createStub(UserModelFactoryInterface::class);
29+
$userFactoryStub->method('create')->willReturn($userSpy);
30+
31+
$sut = $this->getSut(userFactory: $userFactoryStub);
32+
33+
$sut->loginUser($userId);
34+
}
35+
36+
private function getSut(
37+
UserModelFactoryInterface $userFactory = null,
38+
): UserLoginAdapter {
39+
return new UserLoginAdapter(
40+
userFactory: $userFactory ?? $this->createStub(UserModelFactoryInterface::class),
41+
);
42+
}
43+
}

tests/Unit/Authentication/TwoFactorAuth/Service/TwoFAUserServiceTest.php

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@
99

1010
namespace OxidEsales\SecurityModule\Tests\Unit\Authentication\TwoFactorAuth\Service;
1111

12-
use OxidEsales\Eshop\Application\Model\User;
1312
use OxidEsales\Eshop\Core\Utils;
1413
use OxidEsales\EshopCommunity\Internal\Framework\Session\SessionInterface;
1514
use OxidEsales\SecurityModule\Authentication\Service\InternalRedirectServiceInterface;
16-
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Infrastructure\Factory\UserModelFactoryInterface;
15+
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Infrastructure\Service\UserLoginAdapterInterface;
1716
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Service\TwoFAServiceInterface;
1817
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Service\TwoFAUserService;
1918
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Settings\TwoFASettingsInterface;
@@ -84,13 +83,10 @@ public function isChallengeVerifiedProxiesToTwoFAService(): void
8483
#[Test]
8584
public function loginUserLoadsUserLoginsClearsSessionAndRedirects(): void
8685
{
87-
$userSpy = $this->createMock(User::class);
88-
$userSpy->expects($this->once())->method('load')->with($userId = uniqid());
89-
$userSpy->method('getFieldData')->with('oxusername')->willReturn($username = uniqid());
90-
$userSpy->expects($this->once())->method('login')->with($username, null, false);
91-
92-
$userFactoryStub = $this->createStub(UserModelFactoryInterface::class);
93-
$userFactoryStub->method('create')->willReturn($userSpy);
86+
$loginAdapterSpy = $this->createMock(UserLoginAdapterInterface::class);
87+
$loginAdapterSpy->expects($this->once())
88+
->method('loginUser')
89+
->with($userId = uniqid());
9490

9591
$sessionSpy = $this->createMock(SessionInterface::class);
9692
$sessionSpy->expects($this->once())
@@ -104,7 +100,7 @@ public function loginUserLoadsUserLoginsClearsSessionAndRedirects(): void
104100
$utilsSpy->expects($this->once())->method('redirect')->with($redirectUrl, false);
105101

106102
$sut = $this->getSut(
107-
userFactory: $userFactoryStub,
103+
loginAdapter: $loginAdapterSpy,
108104
session: $sessionSpy,
109105
redirectService: $redirectServiceStub,
110106
utils: $utilsSpy,
@@ -118,15 +114,15 @@ private function getSut(
118114
TwoFASettingsInterface $settings = null,
119115
Utils $utils = null,
120116
SessionInterface $session = null,
121-
UserModelFactoryInterface $userFactory = null,
117+
UserLoginAdapterInterface $loginAdapter = null,
122118
InternalRedirectServiceInterface $redirectService = null,
123119
): TwoFAUserService {
124120
return new TwoFAUserService(
125121
twoFAService: $twoFAService ?? $this->createStub(TwoFAServiceInterface::class),
126122
settings: $settings ?? $this->createStub(TwoFASettingsInterface::class),
127123
utils: $utils ?? $this->createStub(Utils::class),
128124
session: $session ?? $this->createStub(SessionInterface::class),
129-
userFactory: $userFactory ?? $this->createStub(UserModelFactoryInterface::class),
125+
loginAdapter: $loginAdapter ?? $this->createStub(UserLoginAdapterInterface::class),
130126
redirectService: $redirectService ?? $this->createStub(InternalRedirectServiceInterface::class),
131127
);
132128
}

0 commit comments

Comments
 (0)