Skip to content

Commit

Permalink
Drop PHP < 7.1 support
Browse files Browse the repository at this point in the history
  • Loading branch information
kelunik committed Jun 21, 2021
1 parent 7676d84 commit 2cb44e3
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 34 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
/composer.lock
/vendor/
/.php_cs.cache
/.phpunit.result.cache
13 changes: 8 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,21 @@
}
],
"require": {
"php": ">=5.5",
"paragonie/random_compat": ">=2",
"paragonie/constant_time_encoding": "^1|^2",
"symfony/polyfill-php56": "^1.1"
"php": ">=7.1",
"paragonie/constant_time_encoding": "^1|^2"
},
"require-dev": {
"amphp/php-cs-fixer-config": "dev-master",
"phpunit/phpunit": "^4.8|^5.3"
"phpunit/phpunit": "^7 | ^8 | ^9"
},
"autoload": {
"psr-4": {
"Kelunik\\TwoFactor\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Kelunik\\TwoFactor\\": "test"
}
}
}
23 changes: 6 additions & 17 deletions src/Oath.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,14 @@

use ParagonIE\ConstantTime\Base32;

/** @final */
class Oath
{
private $length;
private $windowSize;

public function __construct($length = 6, $windowSize = 30)
public function __construct(int $length = 6, int $windowSize = 30)
{
if (!\is_int($length)) {
throw new \InvalidArgumentException("Length must be int");
}

if (!\is_int($windowSize)) {
throw new \InvalidArgumentException("Window size must be int");
}

$this->length = $length;
$this->windowSize = $windowSize;
}
Expand Down Expand Up @@ -111,7 +104,7 @@ public function verifyTotp($key, $value, $graceWindows = 2, $currentTime = null)
$valid = false;

for ($i = 0; $i <= $graceWindows; $i++) {
$hotp = self::generateHotp($key, $this->getTimeWindow($currentTime));
$hotp = $this->generateHotp($key, $this->getTimeWindow($currentTime));
$currentValid = \hash_equals($hotp, $value);

$valid = $valid || $currentValid;
Expand Down Expand Up @@ -145,21 +138,17 @@ public function getUri($key, $issuer, $account)
]);
}

private function getTimeWindow($time = null)
private function getTimeWindow(int $time = null): int
{
$time = $time ?: \time();

if (!\is_int($time)) {
throw new \InvalidArgumentException("Time must be int");
}

return (int) \floor($time / $this->windowSize);
}

/**
* @see https://tools.ietf.org/html/rfc4226#section-5.3
*/
private function oathTruncate($rawHmac)
private function oathTruncate($rawHmac): int
{
// Take lower 4 bit as offset
$offset = \ord($rawHmac[19]) & 0x0F;
Expand All @@ -169,6 +158,6 @@ private function oathTruncate($rawHmac)

// Mask first bit due to signed / unsigned modulo operations
// And extract HOTP value according to OTP_LENGTH
return ($p[1] & 0x7FFFFFFF) % \pow(10, $this->length);
return ($p[1] & 0x7FFFFFFF) % (10 ** $this->length);
}
}
27 changes: 15 additions & 12 deletions test/OathTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,29 @@

namespace Kelunik\TwoFactor;

class OathTest extends \PHPUnit_Framework_TestCase
use PHPUnit\Framework\TestCase;

class OathTest extends TestCase
{
const KEY = "12345678901234567890";
private const KEY = "12345678901234567890";

/** @var Oath */
private $oath;

public function setUp()
public function setUp(): void
{
$this->oath = new Oath(8, 30);
}

/**
* @dataProvider provideRfcTestDataForGeneration
*/
public function testGeneration($time, $totp)
public function testGeneration($time, $totp): void
{
$this->assertSame($totp, $this->oath->generateTotp(self::KEY, $time));
}

public function provideRfcTestDataForGeneration()
public function provideRfcTestDataForGeneration(): array
{
return [
[59, "94287082"],
Expand All @@ -37,12 +39,12 @@ public function provideRfcTestDataForGeneration()
/**
* @dataProvider provideRfcTestDataForValidation
*/
public function testValidation($time, $totp, $result)
public function testValidation($time, $totp, $result): void
{
$this->assertSame($result, $this->oath->verifyTotp(self::KEY, $totp, 2, $time));
}

public function provideRfcTestDataForValidation()
public function provideRfcTestDataForValidation(): array
{
return [
[0, "94287082", false],
Expand All @@ -58,12 +60,12 @@ public function provideRfcTestDataForValidation()
/**
* @dataProvider provideKeyLengths
*/
public function testGenerateKeyHasCorrectLength($length)
public function testGenerateKeyHasCorrectLength($length): void
{
$this->assertSame($length, \strlen($this->oath->generateKey($length)));
}

public function provideKeyLengths()
public function provideKeyLengths(): array
{
return [
[16],
Expand All @@ -75,14 +77,15 @@ public function provideKeyLengths()

/**
* @dataProvider provideInvalidKeyLengths
* @expectedException \InvalidArgumentException
*/
public function testRejectsTooShortKeyLength($length)
public function testRejectsTooShortKeyLength($length): void
{
$this->expectException(\InvalidArgumentException::class);

$this->oath->generateKey($length);
}

public function provideInvalidKeyLengths()
public function provideInvalidKeyLengths(): array
{
return [
[-1],
Expand Down

0 comments on commit 2cb44e3

Please sign in to comment.