From ae27d433a6a414de41e017647bb829c59bf83b05 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Sat, 23 Apr 2022 09:24:33 -0600 Subject: [PATCH 1/4] chore: exportignore phpstan, remove nonexistant travis --- .gitattributes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitattributes b/.gitattributes index 6d63e560..128e5dd0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,6 +3,6 @@ /tests export-ignore /.gitattributes export-ignore /.gitignore export-ignore -/.travis.yml export-ignore +/phpstan.neon.dist export-ignore /phpunit.xml.dist export-ignore /.github export-ignore From aaa7bd5e0df64a99fb0de6d32a0c2f0bc1d3a821 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Sat, 23 Apr 2022 11:29:04 -0600 Subject: [PATCH 2/4] remove unused entrypoint.sh --- .github/actions/entrypoint.sh | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100755 .github/actions/entrypoint.sh diff --git a/.github/actions/entrypoint.sh b/.github/actions/entrypoint.sh deleted file mode 100755 index 40402bc8..00000000 --- a/.github/actions/entrypoint.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -l - -apt-get update && \ -apt-get install -y --no-install-recommends \ - git \ - zip \ - curl \ - ca-certificates \ - unzip \ - wget - -curl --silent --show-error https://getcomposer.org/installer | php -php composer.phar self-update - -echo "---Installing dependencies ---" - -# Add compatiblity for libsodium with older versions of PHP -php composer.phar require --dev --with-dependencies paragonie/sodium_compat - -echo "---Running unit tests ---" -vendor/bin/phpunit From 5cd295318707dac903ab0ca672196ab7c4529d51 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Sat, 23 Apr 2022 11:59:10 -0600 Subject: [PATCH 3/4] better cs checking --- .gitattributes | 5 +++-- .github/workflows/tests.yml | 5 ++--- .gitignore | 1 + .php-cs-fixer.dist.php | 24 ++++++++++++++++++++++++ 4 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 .php-cs-fixer.dist.php diff --git a/.gitattributes b/.gitattributes index 128e5dd0..d5d535d9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,9 @@ * text=auto -/tests export-ignore /.gitattributes export-ignore /.gitignore export-ignore +/.github export-ignore +/.php-cs-fixer.dist.php export-ignore /phpstan.neon.dist export-ignore /phpunit.xml.dist export-ignore -/.github export-ignore +/tests export-ignore diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 68d4f10b..fd10d13b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -38,9 +38,8 @@ jobs: php-version: "8.0" - name: Run Script run: | - composer require friendsofphp/php-cs-fixer - vendor/bin/php-cs-fixer fix --diff --dry-run . - vendor/bin/php-cs-fixer fix --rules=native_function_invocation --allow-risky=yes --diff src + composer global require friendsofphp/php-cs-fixer + ~/.composer/vendor/bin/php-cs-fixer fix --diff --dry-run --allow-risky=yes . staticanalysis: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index b22842cb..f720fb76 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ phpunit.phar.asc composer.phar composer.lock .phpunit.result.cache +.php-cs-fixer.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 00000000..fb636632 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,24 @@ +setRules([ + '@PSR2' => true, + 'concat_space' => ['spacing' => 'one'], + 'no_unused_imports' => true, + 'ordered_imports' => true, + 'new_with_braces' => true, + 'method_argument_space' => false, + 'whitespace_after_comma_in_array' => true, + 'return_type_declaration' => [ + 'space_before' => 'none' + ], + 'single_quote' => true, + 'native_function_invocation' => [ + 'strict' => false + ], + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->in(__DIR__) + ) +; From 8587c3f1dc9bd5a9fc2f3340310d709845819dcb Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Sat, 23 Apr 2022 12:00:13 -0600 Subject: [PATCH 4/4] fix according to new rules --- src/JWT.php | 21 +++++++-------- src/Key.php | 6 ++--- tests/JWKTest.php | 10 +++---- tests/JWTTest.php | 68 +++++++++++++++++++++++------------------------ 4 files changed, 52 insertions(+), 53 deletions(-) diff --git a/src/JWT.php b/src/JWT.php index 57d92ba8..98a503e4 100644 --- a/src/JWT.php +++ b/src/JWT.php @@ -2,16 +2,15 @@ namespace Firebase\JWT; -use ArrayAccess; +use DateTime; use DomainException; use Exception; use InvalidArgumentException; use OpenSSLAsymmetricKey; use OpenSSLCertificate; +use stdClass; use TypeError; use UnexpectedValueException; -use DateTime; -use stdClass; /** * JSON Web Token implementation, based on this spec: @@ -111,7 +110,7 @@ public static function decode( if (null === ($payload = static::jsonDecode($payloadRaw))) { throw new UnexpectedValueException('Invalid claims encoding'); } - if (is_array($payload)) { + if (\is_array($payload)) { // prevent PHP Fatal Error in edge-cases when payload is empty array $payload = (object) $payload; } @@ -229,7 +228,7 @@ public static function sign( list($function, $algorithm) = static::$supported_algs[$alg]; switch ($function) { case 'hash_hmac': - if (!is_string($key)) { + if (!\is_string($key)) { throw new InvalidArgumentException('key must be a string when using hmac'); } return \hash_hmac($algorithm, $msg, $key, true); @@ -237,7 +236,7 @@ public static function sign( $signature = ''; $success = \openssl_sign($msg, $signature, $key, $algorithm); // @phpstan-ignore-line if (!$success) { - throw new DomainException("OpenSSL unable to sign data"); + throw new DomainException('OpenSSL unable to sign data'); } if ($alg === 'ES256') { $signature = self::signatureFromDER($signature, 256); @@ -246,10 +245,10 @@ public static function sign( } return $signature; case 'sodium_crypto': - if (!function_exists('sodium_crypto_sign_detached')) { + if (!\function_exists('sodium_crypto_sign_detached')) { throw new DomainException('libsodium is not available'); } - if (!is_string($key)) { + if (!\is_string($key)) { throw new InvalidArgumentException('key must be a string when using EdDSA'); } try { @@ -302,10 +301,10 @@ private static function verify( 'OpenSSL error: ' . \openssl_error_string() ); case 'sodium_crypto': - if (!function_exists('sodium_crypto_sign_verify_detached')) { + if (!\function_exists('sodium_crypto_sign_verify_detached')) { throw new DomainException('libsodium is not available'); } - if (!is_string($keyMaterial)) { + if (!\is_string($keyMaterial)) { throw new InvalidArgumentException('key must be a string when using EdDSA'); } try { @@ -318,7 +317,7 @@ private static function verify( } case 'hash_hmac': default: - if (!is_string($keyMaterial)) { + if (!\is_string($keyMaterial)) { throw new InvalidArgumentException('key must be a string when using hmac'); } $hash = \hash_hmac($algorithm, $msg, $keyMaterial, true); diff --git a/src/Key.php b/src/Key.php index b09ad190..00cf7f2e 100644 --- a/src/Key.php +++ b/src/Key.php @@ -2,10 +2,10 @@ namespace Firebase\JWT; +use InvalidArgumentException; use OpenSSLAsymmetricKey; use OpenSSLCertificate; use TypeError; -use InvalidArgumentException; class Key { @@ -23,10 +23,10 @@ public function __construct( string $algorithm ) { if ( - !is_string($keyMaterial) + !\is_string($keyMaterial) && !$keyMaterial instanceof OpenSSLAsymmetricKey && !$keyMaterial instanceof OpenSSLCertificate - && !is_resource($keyMaterial) + && !\is_resource($keyMaterial) ) { throw new TypeError('Key material must be a string, resource, or OpenSSLAsymmetricKey'); } diff --git a/tests/JWKTest.php b/tests/JWKTest.php index 17dd4a62..4167a2ba 100644 --- a/tests/JWKTest.php +++ b/tests/JWKTest.php @@ -2,8 +2,8 @@ namespace Firebase\JWT; -use PHPUnit\Framework\TestCase; use InvalidArgumentException; +use PHPUnit\Framework\TestCase; use UnexpectedValueException; class JWKTest extends TestCase @@ -69,7 +69,7 @@ public function testParseKeyWithEmptyDValue() $jwkSet['keys'][0]['d'] = null; $keys = JWK::parseKeySet($jwkSet); - $this->assertTrue(is_array($keys)); + $this->assertTrue(\is_array($keys)); } public function testParseJwkKeySet() @@ -79,7 +79,7 @@ public function testParseJwkKeySet() true ); $keys = JWK::parseKeySet($jwkSet); - $this->assertTrue(is_array($keys)); + $this->assertTrue(\is_array($keys)); $this->assertArrayHasKey('jwk1', $keys); self::$keys = $keys; } @@ -125,7 +125,7 @@ public function testDecodeByJwkKeySet() $result = JWT::decode($msg, self::$keys); - $this->assertEquals("foo", $result->sub); + $this->assertEquals('foo', $result->sub); } /** @@ -139,6 +139,6 @@ public function testDecodeByMultiJwkKeySet() $result = JWT::decode($msg, self::$keys); - $this->assertEquals("bar", $result->sub); + $this->assertEquals('bar', $result->sub); } } diff --git a/tests/JWTTest.php b/tests/JWTTest.php index 191e3d2c..64feab7a 100644 --- a/tests/JWTTest.php +++ b/tests/JWTTest.php @@ -3,12 +3,12 @@ namespace Firebase\JWT; use ArrayObject; -use PHPUnit\Framework\TestCase; use DomainException; use InvalidArgumentException; +use PHPUnit\Framework\TestCase; +use stdClass; use TypeError; use UnexpectedValueException; -use stdClass; class JWTTest extends TestCase { @@ -36,8 +36,8 @@ public function testExpiredToken() { $this->expectException(ExpiredException::class); $payload = [ - "message" => "abc", - "exp" => time() - 20]; // time in the past + 'message' => 'abc', + 'exp' => time() - 20]; // time in the past $encoded = JWT::encode($payload, 'my_key', 'HS256'); JWT::decode($encoded, new Key('my_key', 'HS256')); } @@ -46,8 +46,8 @@ public function testBeforeValidTokenWithNbf() { $this->expectException(BeforeValidException::class); $payload = [ - "message" => "abc", - "nbf" => time() + 20]; // time in the future + 'message' => 'abc', + 'nbf' => time() + 20]; // time in the future $encoded = JWT::encode($payload, 'my_key', 'HS256'); JWT::decode($encoded, new Key('my_key', 'HS256')); } @@ -56,8 +56,8 @@ public function testBeforeValidTokenWithIat() { $this->expectException(BeforeValidException::class); $payload = [ - "message" => "abc", - "iat" => time() + 20]; // time in the future + 'message' => 'abc', + 'iat' => time() + 20]; // time in the future $encoded = JWT::encode($payload, 'my_key', 'HS256'); JWT::decode($encoded, new Key('my_key', 'HS256')); } @@ -65,8 +65,8 @@ public function testBeforeValidTokenWithIat() public function testValidToken() { $payload = [ - "message" => "abc", - "exp" => time() + JWT::$leeway + 20]; // time in the future + 'message' => 'abc', + 'exp' => time() + JWT::$leeway + 20]; // time in the future $encoded = JWT::encode($payload, 'my_key', 'HS256'); $decoded = JWT::decode($encoded, new Key('my_key', 'HS256')); $this->assertEquals($decoded->message, 'abc'); @@ -76,8 +76,8 @@ public function testValidTokenWithLeeway() { JWT::$leeway = 60; $payload = [ - "message" => "abc", - "exp" => time() - 20]; // time in the past + 'message' => 'abc', + 'exp' => time() - 20]; // time in the past $encoded = JWT::encode($payload, 'my_key', 'HS256'); $decoded = JWT::decode($encoded, new Key('my_key', 'HS256')); $this->assertEquals($decoded->message, 'abc'); @@ -88,8 +88,8 @@ public function testExpiredTokenWithLeeway() { JWT::$leeway = 60; $payload = [ - "message" => "abc", - "exp" => time() - 70]; // time far in the past + 'message' => 'abc', + 'exp' => time() - 70]; // time far in the past $this->expectException(ExpiredException::class); $encoded = JWT::encode($payload, 'my_key', 'HS256'); $decoded = JWT::decode($encoded, new Key('my_key', 'HS256')); @@ -100,10 +100,10 @@ public function testExpiredTokenWithLeeway() public function testValidTokenWithNbf() { $payload = [ - "message" => "abc", - "iat" => time(), - "exp" => time() + 20, // time in the future - "nbf" => time() - 20]; + 'message' => 'abc', + 'iat' => time(), + 'exp' => time() + 20, // time in the future + 'nbf' => time() - 20]; $encoded = JWT::encode($payload, 'my_key', 'HS256'); $decoded = JWT::decode($encoded, new Key('my_key', 'HS256')); $this->assertEquals($decoded->message, 'abc'); @@ -113,8 +113,8 @@ public function testValidTokenWithNbfLeeway() { JWT::$leeway = 60; $payload = [ - "message" => "abc", - "nbf" => time() + 20]; // not before in near (leeway) future + 'message' => 'abc', + 'nbf' => time() + 20]; // not before in near (leeway) future $encoded = JWT::encode($payload, 'my_key', 'HS256'); $decoded = JWT::decode($encoded, new Key('my_key', 'HS256')); $this->assertEquals($decoded->message, 'abc'); @@ -125,8 +125,8 @@ public function testInvalidTokenWithNbfLeeway() { JWT::$leeway = 60; $payload = [ - "message" => "abc", - "nbf" => time() + 65]; // not before too far in future + 'message' => 'abc', + 'nbf' => time() + 65]; // not before too far in future $encoded = JWT::encode($payload, 'my_key', 'HS256'); $this->expectException(BeforeValidException::class); JWT::decode($encoded, new Key('my_key', 'HS256')); @@ -137,8 +137,8 @@ public function testValidTokenWithIatLeeway() { JWT::$leeway = 60; $payload = [ - "message" => "abc", - "iat" => time() + 20]; // issued in near (leeway) future + 'message' => 'abc', + 'iat' => time() + 20]; // issued in near (leeway) future $encoded = JWT::encode($payload, 'my_key', 'HS256'); $decoded = JWT::decode($encoded, new Key('my_key', 'HS256')); $this->assertEquals($decoded->message, 'abc'); @@ -149,8 +149,8 @@ public function testInvalidTokenWithIatLeeway() { JWT::$leeway = 60; $payload = [ - "message" => "abc", - "iat" => time() + 65]; // issued too far in future + 'message' => 'abc', + 'iat' => time() + 65]; // issued too far in future $encoded = JWT::encode($payload, 'my_key', 'HS256'); $this->expectException(BeforeValidException::class); JWT::decode($encoded, new Key('my_key', 'HS256')); @@ -160,8 +160,8 @@ public function testInvalidTokenWithIatLeeway() public function testInvalidToken() { $payload = [ - "message" => "abc", - "exp" => time() + 20]; // time in the future + 'message' => 'abc', + 'exp' => time() + 20]; // time in the future $encoded = JWT::encode($payload, 'my_key', 'HS256'); $this->expectException(SignatureInvalidException::class); JWT::decode($encoded, new Key('my_key2', 'HS256')); @@ -170,8 +170,8 @@ public function testInvalidToken() public function testNullKeyFails() { $payload = [ - "message" => "abc", - "exp" => time() + JWT::$leeway + 20]; // time in the future + 'message' => 'abc', + 'exp' => time() + JWT::$leeway + 20]; // time in the future $encoded = JWT::encode($payload, 'my_key', 'HS256'); $this->expectException(TypeError::class); JWT::decode($encoded, new Key(null, 'HS256')); @@ -180,8 +180,8 @@ public function testNullKeyFails() public function testEmptyKeyFails() { $payload = [ - "message" => "abc", - "exp" => time() + JWT::$leeway + 20]; // time in the future + 'message' => 'abc', + 'exp' => time() + JWT::$leeway + 20]; // time in the future $encoded = JWT::encode($payload, 'my_key', 'HS256'); $this->expectException(InvalidArgumentException::class); JWT::decode($encoded, new Key('', 'HS256')); @@ -250,7 +250,7 @@ public function testInvalidSegmentCount() public function testInvalidSignatureEncoding() { - $msg = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwibmFtZSI6ImZvbyJ9.Q4Kee9E8o0Xfo4ADXvYA8t7dN_X_bU9K5w6tXuiSjlUxx"; + $msg = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwibmFtZSI6ImZvbyJ9.Q4Kee9E8o0Xfo4ADXvYA8t7dN_X_bU9K5w6tXuiSjlUxx'; $this->expectException(UnexpectedValueException::class); JWT::decode($msg, new Key('secret', 'HS256')); } @@ -333,7 +333,7 @@ public function testDecodesEmptyArrayAsObject() public function testDecodesArraysInJWTAsArray() { $key = 'yma6Hq4XQegCVND8ef23OYgxSrC3IKqk'; - $payload = ['foo' => [1,2,3]]; + $payload = ['foo' => [1, 2, 3]]; $jwt = JWT::encode($payload, $key, 'HS256'); $decoded = JWT::decode($jwt, new Key($key, 'HS256')); $this->assertEquals($payload['foo'], $decoded->foo);