diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f2499f..2e56764 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,9 +22,6 @@ jobs: fail-fast: true matrix: php-version: - - "7.4" - - "8.0" - - "8.1" - "8.2" - "8.3" @@ -63,9 +60,6 @@ jobs: - ubuntu-latest - windows-latest php-version: - - "7.4" - - "8.0" - - "8.1" - "8.2" - "8.3" diff --git a/.phan/config.php b/.phan/config.php index 2ad2500..d0984f9 100644 --- a/.phan/config.php +++ b/.phan/config.php @@ -15,7 +15,7 @@ // that functions removed in php 7.0 exist. // (See `backward_compatibility_checks` for additional options) 'target_php_version' => null, - 'minimum_target_php_version' => '7.4', + 'minimum_target_php_version' => '8.2', // A list of directories that should be parsed for class and // method information. After excluding the directories @@ -53,6 +53,5 @@ ], 'suppress_issue_types' => [ 'PhanAccessMethodInternal', - 'PhanDeprecatedFunction', ], ]; diff --git a/README.md b/README.md index 64a661c..b846593 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ A generator for counter based ([RFC 4226](https://tools.ietf.org/html/rfc4226)) # Documentation ## Requirements -- PHP 7.4+ +- PHP 8.2+ - [`ext-curl`](https://www.php.net/manual/book.curl) for Battle.net and Steam Guard server time synchronization - [`ext-gmp`](https://www.php.net/manual/book.gmp) for Battle.net authenticator secret retrieval (RSA encryption) - [`ext-sodium`](https://www.php.net/manual/book.sodium) for constant time implementations of base64 encode/decode and hex2bin/bin2hex @@ -29,11 +29,11 @@ A generator for counter based ([RFC 4226](https://tools.ietf.org/html/rfc4226)) via terminal: `composer require chillerlan/php-authenticator` -*composer.json* (note: replace `dev-main` with a [version constraint](https://getcomposer.org/doc/articles/versions.md#writing-version-constraints), e.g. `^4.1` - see [releases](https://github.com/chillerlan/php-authenticator/releases) for valid versions) +*composer.json* (note: replace `dev-main` with a [version constraint](https://getcomposer.org/doc/articles/versions.md#writing-version-constraints), e.g. `^5.0` - see [releases](https://github.com/chillerlan/php-authenticator/releases) for valid versions) ```json { "require": { - "php": "^7.4 || ^8.0", + "php": "^8.2", "chillerlan/php-authenticator": "dev-main" } } diff --git a/composer.json b/composer.json index 42d31af..7254e5e 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "chillerlan/php-authenticator", - "description": "A generator for counter- and time based 2-factor authentication codes (Google Authenticator). PHP 7.4+", + "description": "A generator for counter- and time based 2-factor authentication codes (Google Authenticator). PHP 8.2+", "homepage": "https://github.com/chillerlan/php-authenticator", "license": "MIT", "type": "library", @@ -21,8 +21,8 @@ "minimum-stability": "stable", "prefer-stable": true, "require": { - "php": "^7.4 || ^8.0", - "chillerlan/php-settings-container": "^2.1.4 || ^3.0", + "php": "^8.2", + "chillerlan/php-settings-container": "^3.0", "paragonie/constant_time_encoding": "^2.6" }, "require-dev": { @@ -32,7 +32,7 @@ "ext-sodium": "*", "phan/phan": "^5.4", "phpmd/phpmd": "^2.13", - "phpunit/phpunit": "^9.6", + "phpunit/phpunit": "^10.2", "squizlabs/php_codesniffer": "^3.7" }, "suggest": { @@ -50,7 +50,7 @@ }, "scripts": { "phpunit": "@php vendor/bin/phpunit", - "phan": "@php vendor/bin/phan" + "phan": "@php vendor/bin/phan --allow-polyfill-parser" }, "config": { "lock": false, diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 4038465..0d29673 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,23 +1,29 @@ - ./tests + ./tests/ + tests/Authenticators/AuthenticatorInterfaceTestAbstract.php - - - ./src - + + + + + + + ./src + + diff --git a/src/Authenticator.php b/src/Authenticator.php index bacd811..32eb7b3 100644 --- a/src/Authenticator.php +++ b/src/Authenticator.php @@ -13,6 +13,7 @@ use chillerlan\Authenticator\Authenticators\AuthenticatorInterface; use chillerlan\Settings\SettingsContainerInterface; use InvalidArgumentException; +use SensitiveParameter; use function http_build_query; use function rawurlencode; use function sprintf; @@ -30,15 +31,14 @@ */ class Authenticator{ - /** @var \chillerlan\Settings\SettingsContainerInterface|\chillerlan\Authenticator\AuthenticatorOptions */ - protected SettingsContainerInterface $options; - protected AuthenticatorInterface $authenticator; - protected string $mode = AuthenticatorInterface::TOTP; + protected SettingsContainerInterface|AuthenticatorOptions $options; + protected AuthenticatorInterface $authenticator; + protected string $mode = AuthenticatorInterface::TOTP; /** * Authenticator constructor */ - public function __construct(SettingsContainerInterface $options = null, string $secret = null){ + public function __construct(SettingsContainerInterface|AuthenticatorOptions $options = null, string $secret = null){ // phpcs:ignore $this->setOptions($options ?? new AuthenticatorOptions); @@ -54,14 +54,13 @@ public function __construct(SettingsContainerInterface $options = null, string $ * Please note that this will reset the secret phrase stored with the authenticator instance * if a different mode than the current is given. */ - public function setOptions(SettingsContainerInterface $options):self{ + public function setOptions(SettingsContainerInterface|AuthenticatorOptions $options):self{ $this->options = $options; // invoke a new authenticator interface if necessary if(!isset($this->authenticator) || $this->options->mode !== $this->mode){ - $class = AuthenticatorInterface::MODES[$this->options->mode]; $this->mode = $this->options->mode; - $this->authenticator = new $class; + $this->authenticator = new (AuthenticatorInterface::MODES[$this->options->mode])($this->options); } $this->authenticator->setOptions($this->options); @@ -74,7 +73,7 @@ public function setOptions(SettingsContainerInterface $options):self{ * * @codeCoverageIgnore */ - public function setSecret(string $encodedSecret):self{ + public function setSecret(#[SensitiveParameter] string $encodedSecret):self{ $this->authenticator->setSecret($encodedSecret); return $this; @@ -120,7 +119,7 @@ public function code(int $data = null):string{ * * @codeCoverageIgnore */ - public function verify(string $otp, int $data = null):bool{ + public function verify(#[SensitiveParameter] string $otp, int $data = null):bool{ return $this->authenticator->verify($otp, $data); } diff --git a/src/Authenticators/AuthenticatorAbstract.php b/src/Authenticators/AuthenticatorAbstract.php index d311a71..433df9b 100644 --- a/src/Authenticators/AuthenticatorAbstract.php +++ b/src/Authenticators/AuthenticatorAbstract.php @@ -15,6 +15,7 @@ use chillerlan\Settings\SettingsContainerInterface; use InvalidArgumentException; use RuntimeException; +use SensitiveParameter; use function random_bytes; use function time; use function trim; @@ -26,16 +27,15 @@ abstract class AuthenticatorAbstract implements AuthenticatorInterface{ protected const userAgent = 'chillerlanAuthenticator/5.0 +https://github.com/chillerlan/php-authenticator'; - /** @var \chillerlan\Settings\SettingsContainerInterface|\chillerlan\Authenticator\AuthenticatorOptions */ - protected SettingsContainerInterface $options; - protected ?string $secret = null; - protected int $serverTime = 0; - protected int $lastRequestTime = 0; + protected SettingsContainerInterface|AuthenticatorOptions $options; + protected ?string $secret = null; + protected int $serverTime = 0; + protected int $lastRequestTime = 0; /** * AuthenticatorInterface constructor */ - public function __construct(SettingsContainerInterface $options = null){ + public function __construct(SettingsContainerInterface|AuthenticatorOptions $options = null){ // phpcs:ignore $this->setOptions($options ?? new AuthenticatorOptions); } @@ -52,7 +52,7 @@ public function setOptions(SettingsContainerInterface $options):AuthenticatorInt /** * @inheritDoc */ - public function setSecret(string $encodedSecret):AuthenticatorInterface{ + public function setSecret(#[SensitiveParameter] string $encodedSecret):AuthenticatorInterface{ $this->secret = Base32::decode($this->checkEncodedSecret($encodedSecret)); return $this; diff --git a/src/Authenticators/AuthenticatorInterface.php b/src/Authenticators/AuthenticatorInterface.php index 4bbdd00..e822a1b 100644 --- a/src/Authenticators/AuthenticatorInterface.php +++ b/src/Authenticators/AuthenticatorInterface.php @@ -11,6 +11,7 @@ namespace chillerlan\Authenticator\Authenticators; use chillerlan\Settings\SettingsContainerInterface; +use SensitiveParameter; /** * @@ -49,7 +50,7 @@ public function setOptions(SettingsContainerInterface $options):AuthenticatorInt * * @throws \RuntimeException */ - public function setSecret(string $encodedSecret):AuthenticatorInterface; + public function setSecret(#[SensitiveParameter] string $encodedSecret):AuthenticatorInterface; /** * Returns an encoded representation of the current secret phrase @@ -89,14 +90,14 @@ public function getHMAC(int $counter):string; * * @internal */ - public function getCode(string $hmac):int; + public function getCode(#[SensitiveParameter] string $hmac):int; /** * Formats the final output OTP from the given intermediate $code * * @internal */ - public function getOTP(int $code):string; + public function getOTP(#[SensitiveParameter] int $code):string; /** * Creates a new OTP code with the given secret @@ -114,6 +115,6 @@ public function code(int $data = null):string; * - a UNIX timestamp (TOTP) * - a counter value (HOTP) */ - public function verify(string $otp, int $data = null):bool; + public function verify(#[SensitiveParameter] string $otp, int $data = null):bool; } diff --git a/src/Authenticators/BattleNet.php b/src/Authenticators/BattleNet.php index 4afd89c..1545b66 100644 --- a/src/Authenticators/BattleNet.php +++ b/src/Authenticators/BattleNet.php @@ -15,6 +15,7 @@ use chillerlan\Authenticator\Common\Hex; use InvalidArgumentException; use RuntimeException; +use SensitiveParameter; use function array_reverse; use function array_unshift; use function curl_close; @@ -155,7 +156,7 @@ public function getHMAC(int $counter):string{ /** * @inheritDoc */ - public function getOTP(int $code):string{ + public function getOTP(#[SensitiveParameter] int $code):string{ $code %= 100000000; // length is fixed to 8 for Battle.net @@ -182,7 +183,11 @@ public function getServerTime():int{ * Retrieves the secret from Battle.net using the given serial and restore code. * If the public key for the serial is given (from a previous retrieval), it saves a server request. */ - public function restoreSecret(string $serial, string $restore_code, string $public_key = null):array{ + public function restoreSecret( + #[SensitiveParameter] string $serial, + #[SensitiveParameter] string $restore_code, + #[SensitiveParameter] string $public_key = null + ):array{ $serial = $this->cleanSerial($serial); $region = $this->getRegion($serial); @@ -257,7 +262,7 @@ private function getRegion(string $serial):string{ * * @throws \InvalidArgumentException */ - private function cleanSerial(string $serial):string{ + private function cleanSerial(#[SensitiveParameter] string $serial):string{ $serial = str_replace('-', '', strtoupper(trim($serial))); if(!preg_match('/^[CNEUSKR]{2}\d{12}$/', $serial)){ @@ -270,7 +275,7 @@ private function cleanSerial(string $serial):string{ /** * */ - private function formatSerial(string $serial):string{ + private function formatSerial(#[SensitiveParameter] string $serial):string{ $serial = $this->cleanSerial($serial); // split the numeric part into 3x 4 numbers $blocks = str_split(substr($serial, 2), 4); @@ -318,7 +323,7 @@ private function request(string $endpoint, string $region, string $data = null): * Convert restore code char to byte but with appropriate mapping to exclude I,L,O and S. * e.g. A=10 but J=18 not 19 (as I is missing) */ - private function convertRestoreCodeToByte(string $restore_code):string{ + private function convertRestoreCodeToByte(#[SensitiveParameter] string $restore_code):string{ $chars = unpack('C*', $restore_code); foreach($chars as &$c){ @@ -354,7 +359,7 @@ private function convertRestoreCodeToByte(string $restore_code):string{ /** * Convert restore code byte to char but with appropriate mapping to exclude I,L,O and S. */ - private function convertRestoreCodeToChar(string $data):string{ + private function convertRestoreCodeToChar(#[SensitiveParameter] string $data):string{ $chars = unpack('C*', $data); foreach($chars as &$c){ @@ -390,7 +395,7 @@ private function convertRestoreCodeToChar(string $data):string{ /** * */ - private function encrypt(string $data):string{ + private function encrypt(#[SensitiveParameter] string $data):string{ $num = gmp_powm(gmp_import($data), self::rsa_exp_base10, self::rsa_mod_base10); // gmp_init(self::rsa_mod_base16, 16) $zero = gmp_init('0', 10); $ret = []; @@ -406,7 +411,7 @@ private function encrypt(string $data):string{ /** * @throws \RuntimeException */ - private function decrypt(string $data, string $key):string{ + private function decrypt(#[SensitiveParameter] string $data, #[SensitiveParameter] string $key):string{ if(strlen($data) !== strlen($key)){ throw new RuntimeException('The decryption key size and data size doesn\'t match'); diff --git a/src/Authenticators/HOTP.php b/src/Authenticators/HOTP.php index 82da335..7388882 100644 --- a/src/Authenticators/HOTP.php +++ b/src/Authenticators/HOTP.php @@ -11,6 +11,7 @@ namespace chillerlan\Authenticator\Authenticators; use RuntimeException; +use SensitiveParameter; use function hash_equals; use function hash_hmac; use function pack; @@ -51,7 +52,7 @@ public function getHMAC(int $counter):string{ /** * @inheritDoc */ - public function getCode(string $hmac):int{ + public function getCode(#[SensitiveParameter] string $hmac):int{ $data = unpack('C*', $hmac); $b = ($data[strlen($hmac)] & 0xF); // phpcs:ignore @@ -61,7 +62,7 @@ public function getCode(string $hmac):int{ /** * @inheritDoc */ - public function getOTP(int $code):string{ + public function getOTP(#[SensitiveParameter] int $code):string{ $code %= (10 ** $this->options->digits); return str_pad((string)$code, $this->options->digits, '0', STR_PAD_LEFT); @@ -79,7 +80,7 @@ public function code(int $data = null):string{ /** * @inheritDoc */ - public function verify(string $otp, int $data = null):bool{ + public function verify(#[SensitiveParameter] string $otp, int $data = null):bool{ return hash_equals($this->code($data), $otp); } diff --git a/src/Authenticators/SteamGuard.php b/src/Authenticators/SteamGuard.php index f041634..408e441 100644 --- a/src/Authenticators/SteamGuard.php +++ b/src/Authenticators/SteamGuard.php @@ -14,6 +14,7 @@ use chillerlan\Authenticator\Common\Base64; use RuntimeException; +use SensitiveParameter; use function curl_close; use function curl_exec; use function curl_getinfo; @@ -43,7 +44,7 @@ final class SteamGuard extends TOTP{ /** * @inheritDoc */ - public function setSecret(string $encodedSecret):AuthenticatorInterface{ + public function setSecret(#[SensitiveParameter] string $encodedSecret):AuthenticatorInterface{ $this->secret = Base64::decode($this->checkEncodedSecret($encodedSecret)); return $this; @@ -92,7 +93,7 @@ public function getHMAC(int $counter):string{ /** * @inheritDoc */ - public function getOTP(int $code):string{ + public function getOTP(#[SensitiveParameter] int $code):string{ $str = ''; $len = 26; // strlen($this::steamCodeChars) diff --git a/src/Authenticators/TOTP.php b/src/Authenticators/TOTP.php index 63cf322..8714644 100644 --- a/src/Authenticators/TOTP.php +++ b/src/Authenticators/TOTP.php @@ -10,6 +10,7 @@ namespace chillerlan\Authenticator\Authenticators; +use SensitiveParameter; use function floor; use function hash_equals; use function time; @@ -35,7 +36,7 @@ public function getCounter(int $data = null):int{ /** * @inheritDoc */ - public function verify(string $otp, int $data = null):bool{ + public function verify(#[SensitiveParameter] string $otp, int $data = null):bool{ $limit = $this->options->adjacent; if($limit === 0){ diff --git a/src/Common/Base32.php b/src/Common/Base32.php index 2fb6a9b..863b2fa 100644 --- a/src/Common/Base32.php +++ b/src/Common/Base32.php @@ -12,6 +12,7 @@ use InvalidArgumentException; use ParagonIE\ConstantTime\Base32 as ConstantTimeBase32; +use SensitiveParameter; use function preg_match; /** @@ -32,14 +33,14 @@ final class Base32{ /** * Encode a string to Base32 */ - public static function encode(string $str):string{ + public static function encode(#[SensitiveParameter] string $str):string{ return ConstantTimeBase32::encodeUpperUnpadded($str); } /** * Decode a string from Base32 */ - public static function decode(string $base32):string{ + public static function decode(#[SensitiveParameter] string $base32):string{ self::checkCharacterSet($base32); return ConstantTimeBase32::decodeNoPadding($base32, true); @@ -48,7 +49,7 @@ public static function decode(string $base32):string{ /** * @throws \InvalidArgumentException */ - public static function checkCharacterSet(string $base32):void{ + public static function checkCharacterSet(#[SensitiveParameter] string $base32):void{ if(!preg_match('/^['.self::CHARSET.']+$/', $base32)){ throw new InvalidArgumentException('Base32 must match RFC3548 character set'); diff --git a/src/Common/Base64.php b/src/Common/Base64.php index f199a79..67feb8c 100644 --- a/src/Common/Base64.php +++ b/src/Common/Base64.php @@ -12,6 +12,7 @@ use InvalidArgumentException; use ParagonIE\ConstantTime\Base64 as ConstantTimeBase64; +use SensitiveParameter; use function function_exists; use function preg_match; @@ -33,7 +34,7 @@ class Base64{ /** * Encode a string to Base64 */ - public static function encode(string $str):string{ + public static function encode(#[SensitiveParameter] string $str):string{ if(function_exists('sodium_bin2base64')){ return sodium_bin2base64($str, \SODIUM_BASE64_VARIANT_ORIGINAL); @@ -45,7 +46,7 @@ public static function encode(string $str):string{ /** * Decode a string from Base64 */ - public static function decode(string $base64):string{ + public static function decode(#[SensitiveParameter] string $base64):string{ self::checkCharacterSet($base64); if(function_exists('sodium_base642bin')){ @@ -58,7 +59,7 @@ public static function decode(string $base64):string{ /** * @throws \InvalidArgumentException */ - public static function checkCharacterSet(string $base64):void{ + public static function checkCharacterSet(#[SensitiveParameter] string $base64):void{ if(!preg_match('#^[a-z\d/=+]+$#i', $base64)){ throw new InvalidArgumentException('Base64 must match RFC4648 character set'); diff --git a/src/Common/Hex.php b/src/Common/Hex.php index 8a1db69..b768517 100644 --- a/src/Common/Hex.php +++ b/src/Common/Hex.php @@ -12,6 +12,7 @@ use InvalidArgumentException; use ParagonIE\ConstantTime\Hex as ConstantTimeHex; +use SensitiveParameter; use function preg_match; /** @@ -31,7 +32,7 @@ class Hex{ * * @codeCoverageIgnore */ - public static function encode(string $str):string{ + public static function encode(#[SensitiveParameter] string $str):string{ if(function_exists('sodium_bin2hex')){ return sodium_bin2hex($str); @@ -45,7 +46,7 @@ public static function encode(string $str):string{ * * @codeCoverageIgnore */ - public static function decode(string $hex):string{ + public static function decode(#[SensitiveParameter] string $hex):string{ self::checkCharacterSet($hex); if(function_exists('sodium_hex2bin')){ @@ -58,7 +59,7 @@ public static function decode(string $hex):string{ /** * @throws \InvalidArgumentException */ - public static function checkCharacterSet(string $hex):void{ + public static function checkCharacterSet(#[SensitiveParameter] string $hex):void{ if(!preg_match('#^[a-f\d]+$#i', $hex)){ throw new InvalidArgumentException('hex string must match hexadecimal character set: 0-9, A-F, a-f'); diff --git a/tests/Authenticators/HOTPTest.php b/tests/Authenticators/HOTPTest.php index c2ac298..5aad4f8 100644 --- a/tests/Authenticators/HOTPTest.php +++ b/tests/Authenticators/HOTPTest.php @@ -13,6 +13,7 @@ use chillerlan\Authenticator\AuthenticatorOptions; use chillerlan\Authenticator\Authenticators\{AuthenticatorInterface, HOTP}; use Generator; +use PHPUnit\Framework\Attributes\DataProvider; use function bin2hex; use function sprintf; @@ -49,9 +50,8 @@ public static function hotpVectors():Generator{ /** * @link https://github.com/winauth/winauth/issues/449#issuecomment-353670105 - * - * @dataProvider hotpVectors */ + #[DataProvider('hotpVectors')] public function testHOTP(int $counter, string $hmac, int $code, string $hotp):void{ $this->authenticatorInterface->setSecret($this::secret); diff --git a/tests/Authenticators/SteamGuardTest.php b/tests/Authenticators/SteamGuardTest.php index a44c2e7..3c8c834 100644 --- a/tests/Authenticators/SteamGuardTest.php +++ b/tests/Authenticators/SteamGuardTest.php @@ -14,6 +14,7 @@ use chillerlan\Authenticator\Authenticators\{AuthenticatorInterface, SteamGuard}; use chillerlan\Authenticator\Common\Base64; use Generator; +use PHPUnit\Framework\Attributes\DataProvider; use function date; use function dechex; use function is_int; @@ -51,22 +52,18 @@ public function testSetGetSecret():void{ } public function testCreateSecretDefaultLength():void{ - /** @noinspection PhpUnitTestFailedLineInspection */ $this::markTestSkipped('N/A'); } public function testCreateSecretWithLength():void{ - /** @noinspection PhpUnitTestFailedLineInspection */ $this::markTestSkipped('N/A'); } public function testCreateSecretCheckCharacterSet():void{ - /** @noinspection PhpUnitTestFailedLineInspection */ $this::markTestSkipped('N/A'); } public function testCreateSecretException():void{ - /** @noinspection PhpUnitTestFailedLineInspection */ $this::markTestSkipped('N/A'); } @@ -86,9 +83,7 @@ public static function steamGuardVectors():Generator{ } } - /** - * @dataProvider steamGuardVectors - */ + #[DataProvider('steamGuardVectors')] public function testIntermediateValues(int $timestamp, string $timeslice, string $totp):void{ $this->authenticatorInterface->setSecret($this::secret); @@ -103,9 +98,7 @@ public function testIntermediateValues(int $timestamp, string $timeslice, string $this::assertSame($totp, $code_formatted); } - /** - * @dataProvider steamGuardVectors - */ + #[DataProvider('steamGuardVectors')] public function testAdjacent(int $timestamp, string $timeslice, string $totp):void{ $adjacent = 20; $limit = (2 * $adjacent); diff --git a/tests/Authenticators/TOTPTest.php b/tests/Authenticators/TOTPTest.php index 7e08ea2..861ffea 100644 --- a/tests/Authenticators/TOTPTest.php +++ b/tests/Authenticators/TOTPTest.php @@ -13,6 +13,7 @@ use chillerlan\Authenticator\AuthenticatorOptions; use chillerlan\Authenticator\Authenticators\{AuthenticatorInterface, TOTP}; use Generator; +use PHPUnit\Framework\Attributes\DataProvider; use function date; use function dechex; use function is_int; @@ -76,9 +77,7 @@ public static function totpVectors():Generator{ } } - /** - * @dataProvider totpVectors - */ + #[DataProvider('totpVectors')] public function testIntermediateValues(string $algorithm, int $timestamp, string $timeslice, int $code, string $totp):void{ $this->options->digits = 8; $this->options->algorithm = $algorithm; @@ -98,9 +97,7 @@ public function testIntermediateValues(string $algorithm, int $timestamp, string $this::assertTrue($this->authenticatorInterface->verify($totp, $timestamp)); } - /** - * @dataProvider totpVectors - */ + #[DataProvider('totpVectors')] public function testAdjacent(string $algorithm, int $timestamp, string $timeslice, int $code, string $totp):void{ $adjacent = 20; $limit = (2 * $adjacent); diff --git a/tests/Common/Base32Test.php b/tests/Common/Base32Test.php index c03a907..298cebc 100644 --- a/tests/Common/Base32Test.php +++ b/tests/Common/Base32Test.php @@ -12,6 +12,7 @@ use chillerlan\Authenticator\Common\Base32; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; class Base32Test extends TestCase{ @@ -29,24 +30,18 @@ public static function base32DataProvider():array{ ]; } - /** - * @dataProvider base32DataProvider - */ + #[DataProvider('base32DataProvider')] public function testEncode(string $str, string $base32):void{ $this::assertSame($base32, Base32::encode($str)); } - /** - * @dataProvider base32DataProvider - */ - public function testDecode(string $str, string $base32):void{ + #[DataProvider('base32DataProvider')] + public function testDecode(string $str, string $base32){ $this::assertSame($str, Base32::decode($base32)); } - /** - * @dataProvider base32DataProvider - */ - public function testCheckCharset(string $str, string $base32):void{ + #[DataProvider('base32DataProvider')] + public function testCheckCharset(string $str, string $base32){ $this->expectNotToPerformAssertions(); Base32::checkCharacterSet($base32); diff --git a/tests/Common/Base64Test.php b/tests/Common/Base64Test.php index 7c8d0fa..7a552ba 100644 --- a/tests/Common/Base64Test.php +++ b/tests/Common/Base64Test.php @@ -12,6 +12,7 @@ use chillerlan\Authenticator\Common\Base64; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use function base64_decode; use function base64_encode; @@ -34,9 +35,7 @@ public static function base64DataProvider():array{ ]; } - /** - * @dataProvider base64DataProvider - */ + #[DataProvider('base64DataProvider')] public function testEncode(string $str, string $base64):void{ $encoded = Base64::encode($str); $this::assertSame($base64, $encoded); @@ -44,10 +43,8 @@ public function testEncode(string $str, string $base64):void{ $this::assertSame(base64_encode($str), $encoded); } - /** - * @dataProvider base64DataProvider - */ - public function testDecode(string $str, string $base64):void{ + #[DataProvider('base64DataProvider')] + public function testDecode(string $str, string $base64){ $decoded = Base64::decode($base64); $this::assertSame($str, $decoded); @@ -55,10 +52,8 @@ public function testDecode(string $str, string $base64):void{ $this::assertSame(base64_decode($base64), $decoded); } - /** - * @dataProvider base64DataProvider - */ - public function testCheckCharset(string $str, string $base64):void{ + #[DataProvider('base64DataProvider')] + public function testCheckCharset(string $str, string $base64){ $this->expectNotToPerformAssertions(); Base64::checkCharacterSet($base64); diff --git a/tests/Common/HexTest.php b/tests/Common/HexTest.php index 298ee39..97b1538 100644 --- a/tests/Common/HexTest.php +++ b/tests/Common/HexTest.php @@ -12,6 +12,7 @@ use chillerlan\Authenticator\Common\Hex; use InvalidArgumentException; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use function bin2hex; use function hex2bin; @@ -34,9 +35,7 @@ public static function hexDataProvider():array{ ]; } - /** - * @dataProvider hexDataProvider - */ + #[DataProvider('hexDataProvider')] public function testEncode(string $str, string $hex):void{ $encoded = Hex::encode($str); $this::assertSame($hex, $encoded); @@ -44,9 +43,7 @@ public function testEncode(string $str, string $hex):void{ $this::assertSame(bin2hex($str), $encoded); } - /** - * @dataProvider hexDataProvider - */ + #[DataProvider('hexDataProvider')] public function testDecode(string $str, string $hex):void{ $decoded = Hex::decode($hex); @@ -55,9 +52,7 @@ public function testDecode(string $str, string $hex):void{ $this::assertSame(hex2bin($hex), $decoded); } - /** - * @dataProvider hexDataProvider - */ + #[DataProvider('hexDataProvider')] public function testCheckCharset(string $str, string $hex):void{ $this->expectNotToPerformAssertions();