fuc/vendor/vectorface/googleauthenticator/tests/GoogleAuthenticatorTest.php
2025-02-23 13:30:57 +08:00

222 lines
6.0 KiB
PHP
Executable File

<?php
namespace Tests\Vectorface;
use Exception;
use PHPUnit\Framework\TestCase;
use Vectorface\GoogleAuthenticator;
use Vectorface\OtpAuth\Paramters\Algorithm;
class GoogleAuthenticatorTest extends TestCase
{
/* @var GoogleAuthenticator $googleAuthenticator */
protected $googleAuthenticator;
protected function setUp() : void
{
$this->googleAuthenticator = new GoogleAuthenticator();
}
public function testItCanBeInstantiated()
{
$ga = new GoogleAuthenticator();
$this->assertInstanceOf(GoogleAuthenticator::class, $ga);
}
/**
* @throws Exception
*/
public function testCreateSecretDefaultsToSixteenCharacters()
{
$ga = $this->googleAuthenticator;
$secret = $ga->createSecret();
$this->assertEquals(16, strlen($secret));
}
public function secretLengthProvider()
{
return [
range(0, 200)
];
}
/**
* @dataProvider secretLengthProvider
* @param int $secretLength
* @throws Exception
*/
public function testCreateSecretLengthCanBeSpecified(int $secretLength)
{
$ga = $this->googleAuthenticator;
if ($secretLength < 16 || $secretLength > 128) {
$this->expectException(Exception::class);
$this->expectExceptionMessage('Bad secret length');
}
$secret = $ga->createSecret($secretLength);
$this->assertEquals(strlen($secret), $secretLength);
}
public function codeProvider()
{
// Secret, time, code, passes
return [
['SECRET', 0, '200470', true],
['SECRET', 1385909245, '780018', true],
['SECRET', 1378934578, '705013', true],
['SECRET', 1378934578, '000000', false],
];
}
/**
* @dataProvider codeProvider
* @param string $secret
* @param int|null $timeSlice
* @param string $code
* @param bool $passes
* @throws Exception
*/
public function testGetCodeReturnsCorrectValues(string $secret, ?int $timeSlice, string $code, bool $passes)
{
$generatedCode = $this->googleAuthenticator->getCode($secret, $timeSlice);
if ($passes) {
$this->assertEquals($code, $generatedCode);
} else {
$this->assertNotEquals($code, $generatedCode);
}
}
/**
* @throws Exception
*/
public function testGetQRCodeUrl()
{
$secret = 'SECRET';
$name = 'Test';
$url = $this->googleAuthenticator->getQRCodeUrl($name, $secret);
$prefix = 'data:image/png;base64,';
$this->assertStringStartsWith($prefix, $url);
$base64part = substr($url, strlen($prefix));
$this->assertMatchesRegularExpression("#^[a-zA-Z0-9/+]*={0,2}$#", $base64part);
}
/**
* @throws Exception
*/
public function testVerifyCode()
{
// Good result
$secret = 'SECRET';
$code = $this->googleAuthenticator->getCode($secret);
$result = $this->googleAuthenticator->verifyCode($secret, $code);
$this->assertEquals(true, $result);
// Wrong length
$code = 'INVALIDCODE';
$result = $this->googleAuthenticator->verifyCode($secret, $code);
$this->assertEquals(false, $result);
// Wrong code
$code = '123456';
$result = $this->googleAuthenticator->verifyCode($secret, $code);
$this->assertEquals(false, $result);
// Bad secret
$result = $this->googleAuthenticator->verifyCode('', $code);
$this->assertEquals(false, $result);
}
/**
* @throws Exception
*/
public function testVerifyCodeWithLeadingZero()
{
$secret = 'SECRET';
$code = $this->googleAuthenticator->getCode($secret);
$result = $this->googleAuthenticator->verifyCode($secret, $code);
$this->assertEquals(true, $result);
$code = '0'.$code;
$result = $this->googleAuthenticator->verifyCode($secret, $code);
$this->assertEquals(false, $result);
}
public function testSetCodeLength()
{
$result = $this->googleAuthenticator->setCodeLength(6);
$this->assertInstanceOf(GoogleAuthenticator::class, $result);
}
public function badSecretProvider()
{
return [
"Empty secrets not allowed" => [''],
"Only allows uppercase letters" => ['n'],
"Not correct number of = padding" => ['=='],
"Padding = should only appear at the end" => ['===A==='],
];
}
/**
* @dataProvider badSecretProvider
* @param string $secret
* @throws Exception
*/
public function testGetCodeWithBadSecret(string $secret)
{
$this->expectException(Exception::class);
$this->expectExceptionMessage('Could not decode secret');
$code = $this->googleAuthenticator->getCode($secret);
$this->assertEquals('', $code);
}
/**
* Ensure URL builder emits correctly with minimal params
* @return void
*/
public function testUriBuilderDefaults()
{
$builder = $this->googleAuthenticator->getUriBuilder()
->account("foo")
->secret("bar");
$this->assertEquals("otpauth://totp/foo?secret=bar", "$builder");
}
/**
* Ensure URL builder emits all params correctly
*
* @return void
* @throws Exception
*/
public function testUriBuilderParams()
{
$secret = $this->googleAuthenticator->createSecret();
$digits = 8;
$period = 60;
$algorithm = Algorithm::SHA256;
$builder = $this->googleAuthenticator
->setCodeLength(8)
->getUriBuilder()
->account("foo")
->secret($secret)
->issuer("bar+baz&quux")
->algorithm($algorithm)
->period($period);
$this->assertEquals(
"otpauth://totp/bar%2Bbaz%26quux:%20foo?secret={$secret}&issuer=bar%2Bbaz%26quux&algorithm={$algorithm->value}&digits={$digits}&period={$period}",
"$builder"
);
}
}