Skip to content

Commit 4381bca

Browse files
OXDEV-9927 Create Transput and add resend code
1 parent 50fc1a0 commit 4381bca

16 files changed

Lines changed: 135 additions & 26 deletions

File tree

src/Authentication/TwoFactorAuth/Controller/TwoFactorAuthController.php

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,35 @@
33
namespace OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Controller;
44

55
use OxidEsales\Eshop\Application\Controller\FrontendController;
6-
use OxidEsales\Eshop\Core\Registry;
76
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Service\AuthorizeServiceInterface;
7+
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Transput\OTPRequestInterface;
88

99
class TwoFactorAuthController extends FrontendController
1010
{
1111
protected $_sThisTemplate = '@oe_security_module/templates/two_factor_auth';
1212

13-
private function handleOTP(): void
13+
public function handleOTP(): void
1414
{
15-
$code = Registry::getRequest()->getRequestEscapedParameter('code');
16-
$sessionUser = Registry::getSession()->getVariable('usr');
17-
$user = oxNew(User::class);
18-
$user->load($sessionUser);
15+
$OTPRequest = $this->getService(OTPRequestInterface::class);
1916

20-
$this->getService(OTPServiceInterface::class)->validateCode($user, $code);
17+
//todo: catch only OTP exception that will be shown to user, maybe some abstract OTP exception?
18+
try {
19+
$authorizeService = $this->getService(AuthorizeServiceInterface::class);
20+
$authorizeService->validate(
21+
$OTPRequest->getOTPCode()
22+
);
23+
} catch (\Exception $e) {
24+
//todo: display error message to user
25+
}
2126
}
2227

23-
public function render()
28+
public function generate(): void
2429
{
30+
//todo: stop execution if not ajax
31+
//todo: prevent spam by rate limiting
32+
//todo: should return json response with success or error message
33+
2534
$authorizeService = $this->getService(AuthorizeServiceInterface::class);
2635
$authorizeService->generate();
27-
28-
exit;
2936
}
3037
}

src/Authentication/TwoFactorAuth/DTO/User.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,11 @@ public function getAttempts(): ?int
3838

3939
public function getExpiresAt(): ?DateTimeImmutable
4040
{
41+
//todo: possible bug - should be null if not set
42+
$expireAt = $this->expiresAt ?? time();
43+
4144
$dateTime = new DateTimeImmutable();
4245

43-
return $dateTime->setTimestamp($this->expiresAt);
46+
return $dateTime->setTimestamp($expireAt);
4447
}
4548
}

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
class UserRepository implements UserRepositoryInterface
1818
{
1919
public function __construct(
20-
private UserFactoryInterface $userFactory,
20+
private readonly UserFactoryInterface $userFactory,
2121
private readonly QueryBuilderFactoryInterface $queryBuilderFactory,
2222
) {
2323
}
@@ -31,9 +31,9 @@ public function getUserOTPData(string $userId): UserDTO
3131

3232
return new UserDTO(
3333
$userModel->getId(),
34-
$userModel->getFieldData('OTPCODE'),
35-
(int) $userModel->getFieldData('OTPATTEMPTS'),
36-
new DateTime($userModel->getFieldData('OTPEXPIRETIME'))
34+
$userModel->getFieldData('OESMOTPCODE'),
35+
(int) $userModel->getFieldData('OESMOTPATTEMPTS'),
36+
(int) $userModel->getFieldData('OESMOTPEXPTIME')
3737
);
3838
}
3939

@@ -66,21 +66,21 @@ public function resetCodeFields(string $userId): void
6666
$userModel = $this->userFactory->create();
6767
$userModel->load($userId);
6868
$userModel->assign([
69-
'OESMOTPCODE' => '',
70-
'OESMOTPEXPTIME' => 0,
71-
'OESMOTPATTEMPTS' => 0,
69+
'OESMOTPCODE' => '',
70+
'OESMOTPEXPTIME' => 0,
71+
'OESMOTPATTEMPTS' => 0,
7272
]);
7373
$userModel->save();
7474
}
7575

7676
public function getUserPasswordHash(string $userName): string
7777
{
78-
$qb = $this->queryBuilderFactory->create();
79-
$qb->select('OXPASSWORD')
78+
$builder = $this->queryBuilderFactory->create();
79+
$builder->select('OXPASSWORD')
8080
->from('oxuser')
8181
->where('oxusername = :userName')
8282
->setParameter('userName', $userName);
8383

84-
return $qb->execute()->fetchOne();
84+
return $builder->execute()->fetchOne();
8585
}
8686
}

src/Authentication/TwoFactorAuth/Service/AuthorizeService.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ public function __construct(
1818
) {
1919
}
2020

21-
public function validate(): void
21+
public function validate(string $inputCode): void
2222
{
2323
$activeVerificator = $this->moduleSettings->getTwoFactorAuthType();
2424

2525
$verificator = $this->verificationCollectorService->getVerificator(
2626
$activeVerificator
2727
);
28-
//todo: use transput to get the code from request
28+
2929
//todo: use session to get user id
30-
$verificator->validateCode(uniqid(), uniqid());
30+
$verificator->validateCode('7b4dfcca4669a8bbfcbd29c77cbc82f3', $inputCode);
3131
}
3232

3333
public function generate(): void

src/Authentication/TwoFactorAuth/Service/AuthorizeServiceInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
interface AuthorizeServiceInterface
1111
{
12-
public function validate(): void;
12+
public function validate(string $inputCode): void;
1313

1414
public function generate(): void;
1515
}

src/Authentication/TwoFactorAuth/Service/Verificator/OTP/OTPVerificator.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ public function validateCode(string $userId, string $inputCode): void
4949

5050
public function generate(string $userId): string
5151
{
52+
//todo: stop if user not found?
53+
//todo: wait time between generations, in case of abuse like
54+
//spamming the generate button or
55+
//user hit limit and try to generate new code to bypass it
56+
5257
return $this->otpGenerator->generateCode($userId);
5358
}
5459
}

src/Authentication/TwoFactorAuth/Service/Verificator/OTP/Validator/OTPValidator.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Exception\AttemptLimitExceededException;
1313
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Exception\InvalidCodeException;
1414
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Exception\TimeExpiredException;
15-
use DateTime;
1615

1716
readonly class OTPValidator implements OTPValidatorInterface
1817
{
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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\Transput;
11+
12+
use OxidEsales\EshopCommunity\Internal\Framework\Request\RequestInterface;
13+
14+
readonly class OTPRequest implements OTPRequestInterface
15+
{
16+
public function __construct(
17+
private RequestInterface $request,
18+
) {
19+
}
20+
21+
public function getOTPCode(): string
22+
{
23+
return $this->request->get('auth_code');
24+
}
25+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
/**
4+
* Copyright © OXID eSales AG. All rights reserved.
5+
* See LICENSE file for license details.
6+
*/
7+
8+
namespace OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Transput;
9+
10+
interface OTPRequestInterface
11+
{
12+
public function getOTPCode(): string;
13+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
services:
2+
_defaults:
3+
autowire: true
4+
public: false
5+
6+
OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Transput\OTPRequestInterface:
7+
class: OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Transput\OTPRequest
8+
public: true

0 commit comments

Comments
 (0)