Skip to content

Commit ec53b45

Browse files
committed
OXDEV-9078 Request class should not check the empty code value, only if its not malformed
1 parent 96427d7 commit ec53b45

5 files changed

Lines changed: 31 additions & 59 deletions

File tree

src/Authentication/TwoFactorAuth/Controller/TwoFactorAuthController.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,10 @@ public function __construct(
4242
public function handleOTP(): ?string
4343
{
4444
$userId = $this->twoFAUserService->getPendingUserId();
45+
$code = $this->authCodeRequest->getCode();
4546

4647
try {
47-
$this->twoFAService->verify($userId, $this->authCodeRequest->getCode());
48+
$this->twoFAService->verify($userId, $code);
4849
$this->twoFAUserService->loginUser($userId);
4950
} catch (InvalidCodeException $e) {
5051
$this->utilsView->addErrorToDisplay($e);

src/Authentication/TwoFactorAuth/Service/TwoFAServiceInterface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Service;
99

10-
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Exception\InvalidCodeException;
10+
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Exception\CodeValidationException;
1111

1212
interface TwoFAServiceInterface
1313
{
@@ -18,7 +18,7 @@ public function triggerChallenge(string $userId): void;
1818
public function invalidateChallenge(string $userId): void;
1919

2020
/**
21-
* @throws InvalidCodeException
21+
* @throws CodeValidationException
2222
*/
2323
public function verify(string $userId, #[\SensitiveParameter] string $code): void;
2424

src/Authentication/TwoFactorAuth/Transput/AuthCodeRequest.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
namespace OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Transput;
1111

1212
use OxidEsales\EshopCommunity\Internal\Framework\Request\RequestInterface;
13-
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Exception\InvalidCodeException;
13+
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Exception\MalformedRequestException;
1414

1515
readonly class AuthCodeRequest implements AuthCodeRequestInterface
1616
{
@@ -21,12 +21,11 @@ public function __construct(
2121

2222
public function getCode(): string
2323
{
24-
$code = $this->request->get('auth_code');
25-
26-
if (!is_string($code) || $code === '') {
27-
throw new InvalidCodeException();
24+
$raw = $this->request->get('auth_code');
25+
if (!is_string($raw) && !is_int($raw)) {
26+
throw new MalformedRequestException();
2827
}
2928

30-
return $code;
29+
return (string) $raw;
3130
}
3231
}

src/Authentication/TwoFactorAuth/Transput/AuthCodeRequestInterface.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77

88
namespace OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Transput;
99

10+
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Exception\MalformedRequestException;
11+
1012
interface AuthCodeRequestInterface
1113
{
14+
/** @throws MalformedRequestException */
1215
public function getCode(): string;
1316
}

tests/Unit/Authentication/TwoFactorAuth/Transput/AuthCodeRequestTest.php

Lines changed: 19 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,79 +10,48 @@
1010
namespace OxidEsales\SecurityModule\Tests\Unit\Authentication\TwoFactorAuth\Transput;
1111

1212
use OxidEsales\EshopCommunity\Internal\Framework\Request\RequestInterface;
13-
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Exception\InvalidCodeException;
13+
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Exception\MalformedRequestException;
1414
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Transput\AuthCodeRequest;
1515
use OxidEsales\SecurityModule\Authentication\TwoFactorAuth\Transput\AuthCodeRequestInterface;
16+
use PHPUnit\Framework\Attributes\DataProvider;
1617
use PHPUnit\Framework\TestCase;
1718

1819
class AuthCodeRequestTest extends TestCase
1920
{
20-
public function testGetCodeReturnsValidCode(): void
21+
public static function validCodeDataProvider(): \Generator
2122
{
2223
$code = uniqid();
23-
24-
$requestStub = $this->createStub(RequestInterface::class);
25-
$requestStub->method('get')->with('auth_code')->willReturn($code);
26-
27-
$sut = $this->getSut(
28-
request: $requestStub,
29-
);
30-
31-
$this->assertSame($code, $sut->getCode());
32-
}
33-
34-
public function testGetCodeThrowsExceptionWhenCodeIsEmpty(): void
35-
{
36-
$requestStub = $this->createStub(RequestInterface::class);
37-
$requestStub->method('get')->with('auth_code')->willReturn('');
38-
39-
$sut = $this->getSut(
40-
request: $requestStub,
41-
);
42-
43-
$this->expectException(InvalidCodeException::class);
44-
45-
$sut->getCode();
24+
yield 'string code' => ['input' => $code, 'expected' => $code];
25+
yield 'empty string' => ['input' => '', 'expected' => ''];
26+
yield 'integer code' => ['input' => 123456, 'expected' => '123456'];
4627
}
4728

48-
public function testGetCodeThrowsExceptionWhenCodeIsNull(): void
29+
#[DataProvider('validCodeDataProvider')]
30+
public function testGetCodeReturnsCode(mixed $input, string $expected): void
4931
{
5032
$requestStub = $this->createStub(RequestInterface::class);
51-
$requestStub->method('get')->with('auth_code')->willReturn(null);
52-
53-
$sut = $this->getSut(
54-
request: $requestStub,
55-
);
33+
$requestStub->method('get')->with('auth_code')->willReturn($input);
5634

57-
$this->expectException(InvalidCodeException::class);
35+
$sut = $this->getSut(request: $requestStub);
5836

59-
$sut->getCode();
37+
$this->assertSame($expected, $sut->getCode());
6038
}
6139

62-
public function testGetCodeThrowsExceptionWhenCodeIsArray(): void
40+
public static function invalidCodeDataProvider(): \Generator
6341
{
64-
$requestStub = $this->createStub(RequestInterface::class);
65-
$requestStub->method('get')->with('auth_code')->willReturn(['code']);
66-
67-
$sut = $this->getSut(
68-
request: $requestStub,
69-
);
70-
71-
$this->expectException(InvalidCodeException::class);
72-
73-
$sut->getCode();
42+
yield 'null' => [null];
43+
yield 'array' => [['code']];
7444
}
7545

76-
public function testGetCodeThrowsExceptionWhenCodeIsInteger(): void
46+
#[DataProvider('invalidCodeDataProvider')]
47+
public function testGetCodeThrowsExceptionForInvalidInput(mixed $value): void
7748
{
7849
$requestStub = $this->createStub(RequestInterface::class);
79-
$requestStub->method('get')->with('auth_code')->willReturn(123456);
50+
$requestStub->method('get')->with('auth_code')->willReturn($value);
8051

81-
$sut = $this->getSut(
82-
request: $requestStub,
83-
);
52+
$sut = $this->getSut(request: $requestStub);
8453

85-
$this->expectException(InvalidCodeException::class);
54+
$this->expectException(MalformedRequestException::class);
8655

8756
$sut->getCode();
8857
}

0 commit comments

Comments
 (0)