Skip to content

Commit 1acc83f

Browse files
committed
OXDEV-9992 Add more tests and refactor naming
1 parent 1daefc7 commit 1acc83f

17 files changed

Lines changed: 533 additions & 160 deletions

File tree

metadata.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@
178178
'name' => TwoFactorAuthModuleSettings::TWO_FACTOR_TYPE,
179179
'type' => 'select',
180180
'constraints' => 'otp|totp',
181-
'value' => ''
181+
'value' => 'otp'
182182
],
183183
],
184184
];

src/Authentication/TwoFactorAuth/Infrastructure/Repository/UserRepository.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function getUserOTPData(string $userName): UserDTO
4848
$userData['OXID'],
4949
$userData['OESMOTPATTEMPTS'],
5050
$userData['OESMOTPCODE'],
51-
new DateTime($userData['OESMOTPEXPTIME'])
51+
$userData['OESMOTPEXPTIME'] ? new DateTime($userData['OESMOTPEXPTIME']) : null
5252
);
5353
}
5454

src/Authentication/TwoFactorAuth/Service/ModuleSettingsService.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ public function getTwoFactorAuthType(): string
3333
return $this->getStringValue(self::TWO_FACTOR_TYPE);
3434
}
3535

36+
public function saveIsTwoFactorAuthEnabled(bool $value): void
37+
{
38+
$this->moduleSettingService->saveBoolean(
39+
self::ACTIVE,
40+
$value,
41+
Module::MODULE_ID
42+
);
43+
}
44+
3645
private function getStringValue(string $key): string
3746
{
3847
return $this->moduleSettingService->getString(

src/Authentication/TwoFactorAuth/Service/ModuleSettingsServiceInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ interface ModuleSettingsServiceInterface
1212
public function isTwoFactorAuthEnabled(): bool;
1313

1414
public function getTwoFactorAuthType(): string;
15+
16+
public function saveIsTwoFactorAuthEnabled(bool $value): void;
1517
}

src/Shared/Model/User.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99

1010
namespace OxidEsales\SecurityModule\Shared\Model;
1111

12+
use Doctrine\DBAL\Exception;
1213
use OxidEsales\Eshop\Core\Exception\InputException;
1314
use OxidEsales\Eshop\Core\Exception\UserException;
1415
use OxidEsales\Eshop\Core\Registry;
16+
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Exception\UserNotFoundException;
1517
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Service\UserServiceInterface;
1618
use OxidEsales\SecurityModule\Captcha\Captcha\Image\Exception\CaptchaValidateException as ImageCaptchaException;
1719
use OxidEsales\SecurityModule\Captcha\Captcha\HoneyPot\Exception\CaptchaValidateException as HoneyPotCaptchaException;
@@ -85,7 +87,7 @@ public function login($userName, $password, $setSessionCookie = false): bool
8587

8688
try {
8789
$userService->handleLogin($userName);
88-
} catch (\Exception $e) {
90+
} catch (Exception | UserNotFoundException $e) {
8991
throw oxNew(UserException::class, 'ERROR_MESSAGE_USER_NOVALIDLOGIN');
9092
}
9193

tests/Codeception/Acceptance/BaseCest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
use OxidEsales\EshopCommunity\Core\Di\ContainerFacade;
1414
use OxidEsales\SecurityModule\Authentication\OAuth2\Service\ModuleSettingsServiceInterface
1515
as OAuthModuleSettingsServiceInterface;
16+
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Service\ModuleSettingsServiceInterface
17+
as TwoFASettingsServiceInterface;
1618
use OxidEsales\SecurityModule\Captcha\Service\ModuleSettingsServiceInterface as CaptchaSettingsServiceInterface;
1719
use OxidEsales\SecurityModule\PasswordPolicy\Service\ModuleSettingsServiceInterface as PasswordSettingsServiceInterface;
1820

@@ -38,6 +40,11 @@ protected function setCaptchaState(bool $state)
3840
ContainerFacade::get(CaptchaSettingsServiceInterface::class)->saveIsCaptchaEnabled($state);
3941
}
4042

43+
protected function setTwoFactorAuthState(bool $state)
44+
{
45+
ContainerFacade::get(TwoFASettingsServiceInterface::class)->saveIsTwoFactorAuthEnabled($state);
46+
}
47+
4148
protected function setProviderState(bool $state)
4249
{
4350
$moduleSettings = ContainerFacade::get(OAuthModuleSettingsServiceInterface::class);
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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\Codeception\Acceptance;
11+
12+
use Codeception\Util\Fixtures;
13+
use OxidEsales\Codeception\Module\Translation\Translator;
14+
use OxidEsales\Codeception\Page\Account\UserLogin;
15+
use OxidEsales\Codeception\Page\Account\UserPasswordReminder;
16+
use OxidEsales\Codeception\Page\DataObject\ContactData;
17+
use OxidEsales\SecurityModule\Tests\Codeception\Support\AcceptanceTester;
18+
19+
/**
20+
* @group oe_security_module
21+
* @group oe_security_module_two_fa
22+
*/
23+
class TwoFAAuthenticationCest extends BaseCest
24+
{
25+
private string $otpInput = '#auth_code';
26+
private string $otpSubmitBtn = '#auth_submit';
27+
private string $otpResendBtn = 'RESENT_CODE';
28+
29+
public function _before(AcceptanceTester $I): void
30+
{
31+
$this->setCaptchaState(false);
32+
$this->setPasswordState(false);
33+
$this->setTwoFactorAuthState(true);
34+
}
35+
36+
public function testRedirectToOTPAfterLogin(AcceptanceTester $I): void
37+
{
38+
$userData = $this->getExistingUserData();
39+
40+
$userLoginPage = new UserLogin($I);
41+
$I->amOnPage($userLoginPage->URL);
42+
$I->see(Translator::translate('LOGIN'));
43+
44+
$userLoginPage->login($userData['userLoginName'], $userData['userPassword']);
45+
46+
$I->waitForPageLoad();
47+
$I->seeElement($this->otpInput);
48+
$I->seeElement($this->otpSubmitBtn);
49+
$I->see(Translator::translate($this->otpResendBtn));
50+
}
51+
52+
public function testRedirectToOTPOnLoginBox(AcceptanceTester $I): void
53+
{
54+
55+
$userData = $this->getExistingUserData();
56+
57+
$homePage = $I->openShop();
58+
$accountMenu = $homePage->openAccountMenu();
59+
$I->waitForText(Translator::translate('FORGOT_PASSWORD'));
60+
$I->retryFillField($accountMenu->userLoginName, $userData['userLoginName']);
61+
$I->retryFillField($accountMenu->userLoginPassword, $userData['userPassword']);
62+
$I->retryClick($accountMenu->userLoginButton);
63+
64+
$I->waitForPageLoad();
65+
$I->seeElement($this->otpInput);
66+
$I->seeElement($this->otpSubmitBtn);
67+
$I->see(Translator::translate($this->otpResendBtn));
68+
}
69+
}

tests/Codeception/Support/Data/fixtures.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
SET @@session.sql_mode = '';
22

33
REPLACE INTO `oxuser` (`OXID`, `OXACTIVE`, `OXRIGHTS`, `OXSHOPID`, `OXUSERNAME`, `OXPASSWORD`, `OXPASSSALT`, `OXCUSTNR`, `OXUSTID`, `OXCOMPANY`, `OXFNAME`, `OXLNAME`, `OXSTREET`, `OXSTREETNR`, `OXADDINFO`, `OXCITY`, `OXCOUNTRYID`, `OXZIP`, `OXFON`, `OXFAX`, `OXSAL`, `OXBONI`, `OXCREATE`, `OXREGISTER`, `OXPRIVFON`, `OXMOBFON`, `OXBIRTHDATE`)
4-
VALUES ('testuser', 1, 'user', 1, 'some_test_user@oxid-esales.dev', 'c9dadd994241c9e5fa6469547009328a', '7573657275736572', 8, '', 'UserCompany šÄßüл', 'UserNamešÄßüл', 'UserSurnamešÄßüл', 'Musterstr.šÄßüл', '1', 'User additional info šÄßüл', 'Musterstadt šÄßüл', 'testcountry_de', '79098', '0800 111111', '0800 111112', 'Mr', 500, '2008-02-05 14:42:42', '2008-02-05 14:42:42', '0800 111113', '0800 111114', '1980-01-01');
4+
VALUES ('testuser', 1, 'user', 1, 'some_test_user@oxid-esales.dev', '$2y$10$b186f117054b700a89de9uXDzfahkizUucitfPov3C2cwF5eit2M2', 'b186f117054b700a89de929ce90c6aef', 8, '', 'UserCompany šÄßüл', 'UserNamešÄßüл', 'UserSurnamešÄßüл', 'Musterstr.šÄßüл', '1', 'User additional info šÄßüл', 'Musterstadt šÄßüл', 'testcountry_de', '79098', '0800 111111', '0800 111112', 'Mr', 500, '2008-02-05 14:42:42', '2008-02-05 14:42:42', '0800 111113', '0800 111114', '1980-01-01');
55

66
REPLACE INTO `oxarticles` (`OXID`, `OXSHOPID`, `OXPARENTID`, `OXACTIVE`, `OXARTNUM`, `OXTITLE`, `OXSHORTDESC`, `OXPRICE`, `OXPRICEA`, `OXPRICEB`, `OXPRICEC`, `OXTPRICE`, `OXUNITNAME`, `OXUNITQUANTITY`, `OXVAT`, `OXWEIGHT`, `OXSTOCK`, `OXSTOCKFLAG`, `OXSTOCKTEXT`, `OXNOSTOCKTEXT`, `OXDELIVERY`, `OXINSERT`, `OXTIMESTAMP`, `OXLENGTH`, `OXWIDTH`, `OXHEIGHT`, `OXSEARCHKEYS`, `OXISSEARCH`, `OXVARNAME`, `OXVARSTOCK`, `OXVARCOUNT`, `OXVARSELECT`, `OXVARMINPRICE`, `OXVARMAXPRICE`, `OXVARNAME_1`, `OXVARSELECT_1`, `OXTITLE_1`, `OXSHORTDESC_1`, `OXSEARCHKEYS_1`, `OXBUNDLEID`, `OXSTOCKTEXT_1`, `OXNOSTOCKTEXT_1`, `OXSORT`, `OXVENDORID`, `OXMANUFACTURERID`, `OXMINDELTIME`, `OXMAXDELTIME`, `OXDELTIMEUNIT`)
77
VALUES ('1000', 1, '', 1, '1000', '[DE 4] Test product 0 šÄßüл', 'Test product 0 short desc [DE]', 50, 35, 45, 55, 0, 'kg', 2, NULL, 2, 15, 1, 'In stock [DE]', 'Out of stock [DE]', '0000-00-00', '2008-02-04', '2008-02-04 17:07:48', 1, 2, 2, 'search1000', 1, '', 0, 0, '', 50, 0, '', '', 'Test product 0 [EN] šÄßüл', 'Test product 0 short desc [EN] šÄßüл', 'šÄßüл1000', '', 'In stock [EN] šÄßüл', 'Out of stock [EN] šÄßüл', 0, 'testdistributor', 'testmanufacturer', 1, 1, 'DAY');

tests/Codeception/Support/Data/fixtures_ee.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
SET @@session.sql_mode = '';
22

33
REPLACE INTO `oxuser` (`OXID`, `OXACTIVE`, `OXRIGHTS`, `OXSHOPID`, `OXUSERNAME`, `OXPASSWORD`, `OXPASSSALT`, `OXCUSTNR`, `OXUSTID`, `OXCOMPANY`, `OXFNAME`, `OXLNAME`, `OXSTREET`, `OXSTREETNR`, `OXADDINFO`, `OXCITY`, `OXCOUNTRYID`, `OXZIP`, `OXFON`, `OXFAX`, `OXSAL`, `OXBONI`, `OXCREATE`, `OXREGISTER`, `OXPRIVFON`, `OXMOBFON`, `OXBIRTHDATE`)
4-
VALUES ('testuser', 1, 'user', 1, 'some_test_user@oxid-esales.dev', 'c9dadd994241c9e5fa6469547009328a', '7573657275736572', 8, '', 'UserCompany šÄßüл', 'UserNamešÄßüл', 'UserSurnamešÄßüл', 'Musterstr.šÄßüл', '1', 'User additional info šÄßüл', 'Musterstadt šÄßüл', 'testcountry_de', '79098', '0800 111111', '0800 111112', 'Mr', 500, '2008-02-05 14:42:42', '2008-02-05 14:42:42', '0800 111113', '0800 111114', '1980-01-01');
4+
VALUES ('testuser', 1, 'user', 1, 'some_test_user@oxid-esales.dev', '$2y$10$b186f117054b700a89de9uXDzfahkizUucitfPov3C2cwF5eit2M2', 'b186f117054b700a89de929ce90c6aef', 8, '', 'UserCompany šÄßüл', 'UserNamešÄßüл', 'UserSurnamešÄßüл', 'Musterstr.šÄßüл', '1', 'User additional info šÄßüл', 'Musterstadt šÄßüл', 'testcountry_de', '79098', '0800 111111', '0800 111112', 'Mr', 500, '2008-02-05 14:42:42', '2008-02-05 14:42:42', '0800 111113', '0800 111114', '1980-01-01');
55

66
REPLACE INTO `oxarticles` (`OXID`, `OXMAPID`, `OXSHOPID`, `OXPARENTID`, `OXACTIVE`, `OXARTNUM`, `OXTITLE`, `OXSHORTDESC`, `OXPRICE`, `OXPRICEA`, `OXPRICEB`, `OXPRICEC`, `OXTPRICE`, `OXUNITNAME`, `OXUNITQUANTITY`, `OXVAT`, `OXWEIGHT`, `OXSTOCK`, `OXSTOCKFLAG`, `OXSTOCKTEXT`, `OXNOSTOCKTEXT`, `OXDELIVERY`, `OXINSERT`, `OXTIMESTAMP`, `OXLENGTH`, `OXWIDTH`, `OXHEIGHT`, `OXSEARCHKEYS`, `OXISSEARCH`, `OXVARNAME`, `OXVARSTOCK`, `OXVARCOUNT`, `OXVARSELECT`, `OXVARMINPRICE`, `OXVARMAXPRICE`, `OXVARNAME_1`, `OXVARSELECT_1`, `OXTITLE_1`, `OXSHORTDESC_1`, `OXSEARCHKEYS_1`, `OXBUNDLEID`, `OXSTOCKTEXT_1`, `OXNOSTOCKTEXT_1`, `OXSORT`, `OXVENDORID`, `OXMANUFACTURERID`, `OXMINDELTIME`, `OXMAXDELTIME`, `OXDELTIMEUNIT`)
77
VALUES ('1000', 1, 1, '', 1, '1000', '[DE 4] Test product 0 šÄßüл', 'Test product 0 short desc [DE]', 50, 35, 45, 55, 0, 'kg', 2, NULL, 2, 15, 1, 'In stock [DE]', 'Out of stock [DE]', '0000-00-00', '2008-02-04', '2008-02-04 17:07:48', 1, 2, 2, 'search1000', 1, '', 0, 0, '', 50, 0, '', '', 'Test product 0 [EN] šÄßüл', 'Test product 0 short desc [EN] šÄßüл', 'šÄßüл1000', '', 'In stock [EN] šÄßüл', 'Out of stock [EN] šÄßüл', 0, 'testdistributor', 'testmanufacturer', 1, 1, 'DAY');

tests/Integration/Shared/Model/UserTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,21 @@ public function testLoginWithEmptyCaptcha()
9999
$subject = oxNew(User::class);
100100
$subject->login('', '');
101101
}
102+
103+
public function testLoginWithOtpEnabledAndInvalidPasswordThrows(): void
104+
{
105+
$this->requestMock
106+
->method('getRequestParameter')
107+
->willReturnCallback(function ($param) {
108+
if ($param === 'captcha') {
109+
return 'valid_captcha';
110+
}
111+
return null;
112+
});
113+
114+
$this->expectException(UserException::class);
115+
116+
$subject = oxNew(User::class);
117+
$subject->login(uniqid(), uniqid());
118+
}
102119
}

0 commit comments

Comments
 (0)