From 6116d00add8b01933587ae12d949f2a6c33f241f Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Wed, 17 Apr 2019 14:57:25 +0100 Subject: [PATCH 01/22] Shifted helper and factory methods into their own namespaces and updated tests. --- src/{JwtFactory.php => Factory/Jwt.php} | 8 ++-- .../JwtAuth.php} | 4 +- src/{JwtParse.php => Helper/Parse.php} | 4 +- src/{JwtValidate.php => Helper/Validate.php} | 4 +- .../JwtAuthTest.php} | 24 +++++------ tests/Factory/JwtTest.php | 27 ++++++++++++ .../ParseTest.php} | 18 ++++---- .../ValidateTest.php} | 42 +++++++++---------- tests/JwtFactoryTest.php | 27 ------------ 9 files changed, 79 insertions(+), 79 deletions(-) rename src/{JwtFactory.php => Factory/Jwt.php} (81%) rename src/{JwtAuthFactory.php => Factory/JwtAuth.php} (93%) rename src/{JwtParse.php => Helper/Parse.php} (94%) rename src/{JwtValidate.php => Helper/Validate.php} (96%) rename tests/{JwtAuthFactoryTest.php => Factory/JwtAuthTest.php} (53%) create mode 100644 tests/Factory/JwtTest.php rename tests/{JwtParseTest.php => Helper/ParseTest.php} (65%) rename tests/{JwtValidateTest.php => Helper/ValidateTest.php} (62%) delete mode 100644 tests/JwtFactoryTest.php diff --git a/src/JwtFactory.php b/src/Factory/Jwt.php similarity index 81% rename from src/JwtFactory.php rename to src/Factory/Jwt.php index 69c6a54..26e05bf 100644 --- a/src/JwtFactory.php +++ b/src/Factory/Jwt.php @@ -2,15 +2,15 @@ declare(strict_types=1); -namespace PsrJwt; +namespace PsrJwt\Factory; use ReallySimpleJWT\Build; use ReallySimpleJWT\Validate; use ReallySimpleJWT\Encode; use ReallySimpleJWT\Parse; -use ReallySimpleJWT\Jwt; +use ReallySimpleJWT\Jwt as RSJwt; -class JwtFactory +class Jwt { public static function builder(): Build { @@ -23,7 +23,7 @@ public static function builder(): Build public static function parser(string $token, string $secret): Parse { - $jwt = new Jwt($token, $secret); + $jwt = new RSJwt($token, $secret); return new Parse( $jwt, diff --git a/src/JwtAuthFactory.php b/src/Factory/JwtAuth.php similarity index 93% rename from src/JwtAuthFactory.php rename to src/Factory/JwtAuth.php index 7ac4a47..1e065c7 100644 --- a/src/JwtAuthFactory.php +++ b/src/Factory/JwtAuth.php @@ -2,13 +2,13 @@ declare(strict_types=1); -namespace PsrJwt; +namespace PsrJwt\Factory; use PsrJwt\JwtAuthMiddleware; use PsrJwt\JwtAuthHandler; use PsrJwt\JwtAuthInvokable; -class JwtAuthFactory +class JwtAuth { public static function middleware(): JwtAuthMiddleware { diff --git a/src/JwtParse.php b/src/Helper/Parse.php similarity index 94% rename from src/JwtParse.php rename to src/Helper/Parse.php index 4ad7e10..344fff1 100644 --- a/src/JwtParse.php +++ b/src/Helper/Parse.php @@ -2,11 +2,11 @@ declare(strict_types = 1); -namespace PsrJwt; +namespace PsrJwt\Helper; use Psr\Http\Message\ServerRequestInterface; -class JwtParse +class Parse { private $parsers = []; diff --git a/src/JwtValidate.php b/src/Helper/Validate.php similarity index 96% rename from src/JwtValidate.php rename to src/Helper/Validate.php index aa75b23..734fe2d 100644 --- a/src/JwtValidate.php +++ b/src/Helper/Validate.php @@ -2,12 +2,12 @@ declare(strict_types = 1); -namespace PsrJwt; +namespace PsrJwt\Helper; use ReallySimpleJWT\Parse; use ReallySimpleJWT\Exception\ValidateException; -class JwtValidate +class Validate { private $parse; diff --git a/tests/JwtAuthFactoryTest.php b/tests/Factory/JwtAuthTest.php similarity index 53% rename from tests/JwtAuthFactoryTest.php rename to tests/Factory/JwtAuthTest.php index ad5f8ad..2f16a12 100644 --- a/tests/JwtAuthFactoryTest.php +++ b/tests/Factory/JwtAuthTest.php @@ -1,48 +1,48 @@ assertInstanceOf( JwtAuthMiddleware::class, - JwtAuthFactory::middleware() + JwtAuth::middleware() ); } /** - * @covers PsrJwt\JwtAuthFactory::invokable + * @covers PsrJwt\Factory\JwtAuth::invokable * @uses PsrJwt\JwtAuthHandler::__construct * @uses PsrJwt\JwtAuthInvokable::__construct */ - public function testJwtAuthFactoryInvokable() + public function testJwtAuthInvokable() { $this->assertInstanceOf( JwtAuthInvokable::class, - JwtAuthFactory::invokable('jwt', '$Secret123!') + JwtAuth::invokable('jwt', '$Secret123!') ); } /** - * @covers PsrJwt\JwtAuthFactory::handler + * @covers PsrJwt\Factory\JwtAuth::handler * @uses PsrJwt\JwtAuthHandler::__construct */ - public function testJwtAuthFactoryHandler() + public function testJwtAuthHandler() { $this->assertInstanceOf( JwtAuthHandler::class, - JwtAuthFactory::handler('jwt', '$Secret123!') + JwtAuth::handler('jwt', '$Secret123!') ); } } diff --git a/tests/Factory/JwtTest.php b/tests/Factory/JwtTest.php new file mode 100644 index 0000000..9a15683 --- /dev/null +++ b/tests/Factory/JwtTest.php @@ -0,0 +1,27 @@ +assertInstanceOf(Build::class, Jwt::builder()); + } + + /** + * @covers PsrJwt\Factory\Jwt::parser + */ + public function testJwtParser() + { + $this->assertInstanceOf(Parse::class, Jwt::parser('aaa.bbb.ccc', 'secret')); + } +} diff --git a/tests/JwtParseTest.php b/tests/Helper/ParseTest.php similarity index 65% rename from tests/JwtParseTest.php rename to tests/Helper/ParseTest.php index 0afb861..514892d 100644 --- a/tests/JwtParseTest.php +++ b/tests/Helper/ParseTest.php @@ -3,27 +3,27 @@ namespace Tests; use PHPUnit\Framework\TestCase; -use PsrJwt\JwtParse; +use PsrJwt\Helper\Parse; use Psr\Http\Message\ServerRequestInterface; use PsrJwt\Parser\Bearer; use ReflectionMethod; use Mockery as m; use stdClass; -class JwtParseTest extends TestCase +class ParseTest extends TestCase { /** - * @covers PsrJwt\JwtParse::__construct + * @covers PsrJwt\Helper\Parse::__construct */ - public function testJwtParse() + public function testParse() { - $parse = new JwtParse(['token_key' => 'jwt']); - $this->assertInstanceOf(JwtParse::class, $parse); + $parse = new Parse(['token_key' => 'jwt']); + $this->assertInstanceOf(Parse::class, $parse); } /** - * @covers PsrJwt\JwtParse::findToken - * @uses PsrJwt\JwtParse + * @covers PsrJwt\Helper\Parse::findToken + * @uses PsrJwt\Helper\Parse * @uses PsrJwt\Parser\Bearer */ public function testFindToken() @@ -34,7 +34,7 @@ public function testFindToken() ->once() ->andReturn(['Bearer abc.def.ghi']); - $parse = new JwtParse(['token_key' => 'jwt']); + $parse = new Parse(['token_key' => 'jwt']); $parse->addParser(Bearer::class); $result = $parse->findToken($request); diff --git a/tests/JwtValidateTest.php b/tests/Helper/ValidateTest.php similarity index 62% rename from tests/JwtValidateTest.php rename to tests/Helper/ValidateTest.php index da88602..14f97db 100644 --- a/tests/JwtValidateTest.php +++ b/tests/Helper/ValidateTest.php @@ -1,50 +1,50 @@ setSecret('Secret123!456$') ->setIssuer('localhost') ->setPayloadClaim('exp', time() - 10) ->build() ->getToken(); - $validate = new JwtValidate( - JwtFactory::parser($token, 'Secret123!456$') + $validate = new Validate( + Jwt::parser($token, 'Secret123!456$') ); - $this->assertInstanceOf(JwtValidate::class, $validate); + $this->assertInstanceOf(Validate::class, $validate); } /** - * @covers PsrJwt\JwtValidate::validate - * @uses PsrJwt\JwtValidate + * @covers PsrJwt\Helper\Validate::validate + * @uses PsrJwt\Helper\Validate * @uses PsrJwt\JwtFactory */ - public function testValidate() + public function testValidateTrue() { - $jwt = JwtFactory::builder(); + $jwt = Jwt::builder(); $token = $jwt->setSecret('Secret123!456$') ->setIssuer('localhost') ->setPayloadClaim('exp', time() - 10) ->build() ->getToken(); - $validate = new JwtValidate( - JwtFactory::parser($token, 'Secret123!456$') + $validate = new Validate( + Jwt::parser($token, 'Secret123!456$') ); $result = $validate->validate(); @@ -54,21 +54,21 @@ public function testValidate() } /** - * @covers PsrJwt\JwtValidate::validateNotBefore - * @uses PsrJwt\JwtValidate + * @covers PsrJwt\Helper\Validate::validateNotBefore + * @uses PsrJwt\Helper\Validate * @uses PsrJwt\JwtFactory */ public function testValidateNotBefore() { - $jwt = JwtFactory::builder(); + $jwt = Jwt::builder(); $token = $jwt->setSecret('Secret123!456$') ->setIssuer('localhost') ->setPayloadClaim('nbf', time() + 10) ->build() ->getToken(); - $validate = new JwtValidate( - JwtFactory::parser($token, 'Secret123!456$') + $validate = new Validate( + Jwt::parser($token, 'Secret123!456$') ); $result = $validate->validateNotBefore( diff --git a/tests/JwtFactoryTest.php b/tests/JwtFactoryTest.php deleted file mode 100644 index d315487..0000000 --- a/tests/JwtFactoryTest.php +++ /dev/null @@ -1,27 +0,0 @@ -assertInstanceOf(Build::class, JwtFactory::builder()); - } - - /** - * @covers PsrJwt\JwtFactory::parser - */ - public function testJwtFactoryParser() - { - $this->assertInstanceOf(Parse::class, JwtFactory::parser('aaa.bbb.ccc', 'secret')); - } -} From 35b09a432ea0d35d5b783fcd0e7d7915740ba859 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Wed, 17 Apr 2019 15:09:23 +0100 Subject: [PATCH 02/22] Updated tests and code to work with new helper and factory directory structure. --- src/JwtAuthHandler.php | 12 ++++++------ tests/Helper/ValidateTest.php | 6 +++--- tests/JwtAuthHandlerTest.php | 34 ++++++++++++++++----------------- tests/JwtAuthInvokableTest.php | 16 ++++++++-------- tests/JwtAuthMiddlewareTest.php | 10 +++++----- 5 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/JwtAuthHandler.php b/src/JwtAuthHandler.php index a9400ae..e8584e4 100644 --- a/src/JwtAuthHandler.php +++ b/src/JwtAuthHandler.php @@ -4,9 +4,9 @@ namespace PsrJwt; -use PsrJwt\JwtFactory; -use PsrJwt\JwtValidate; -use PsrJwt\JwtParse; +use PsrJwt\Factory\Jwt; +use PsrJwt\Helper\Validate; +use PsrJwt\Helper\Parse; use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -34,9 +34,9 @@ protected function getSecret(): string protected function validate(string $token): ResponseInterface { - $parse = JwtFactory::parser($token, $this->getSecret()); + $parse = Jwt::parser($token, $this->getSecret()); - $validate = new JwtValidate($parse); + $validate = new Validate($parse); $validationState = $validate->validate(); @@ -66,7 +66,7 @@ private function hasJwt(string $token): bool protected function getToken(ServerRequestInterface $request): string { - $parse = new JwtParse(['token_key' => $this->tokenKey]); + $parse = new Parse(['token_key' => $this->tokenKey]); $parse->addParser(\PsrJwt\Parser\Bearer::class); $parse->addParser(\PsrJwt\Parser\Cookie::class); $parse->addParser(\PsrJwt\Parser\Body::class); diff --git a/tests/Helper/ValidateTest.php b/tests/Helper/ValidateTest.php index 14f97db..321ef35 100644 --- a/tests/Helper/ValidateTest.php +++ b/tests/Helper/ValidateTest.php @@ -11,7 +11,7 @@ class ValidateTest extends TestCase { /** * @covers PsrJwt\Helper\Validate::__construct - * @uses PsrJwt\JwtFactory + * @uses PsrJwt\Factory\Jwt */ public function testValidate() { @@ -32,7 +32,7 @@ public function testValidate() /** * @covers PsrJwt\Helper\Validate::validate * @uses PsrJwt\Helper\Validate - * @uses PsrJwt\JwtFactory + * @uses PsrJwt\Factory\Jwt */ public function testValidateTrue() { @@ -56,7 +56,7 @@ public function testValidateTrue() /** * @covers PsrJwt\Helper\Validate::validateNotBefore * @uses PsrJwt\Helper\Validate - * @uses PsrJwt\JwtFactory + * @uses PsrJwt\Factory\Jwt */ public function testValidateNotBefore() { diff --git a/tests/JwtAuthHandlerTest.php b/tests/JwtAuthHandlerTest.php index 2a039c0..4dace5c 100644 --- a/tests/JwtAuthHandlerTest.php +++ b/tests/JwtAuthHandlerTest.php @@ -4,7 +4,7 @@ use PHPUnit\Framework\TestCase; use PsrJwt\JwtAuthHandler; -use PsrJwt\JwtFactory; +use PsrJwt\Factory\Jwt; use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -28,9 +28,9 @@ public function testJwtAuthHandler() /** * @covers PsrJwt\JwtAuthHandler::handle * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\JwtFactory - * @uses PsrJwt\JwtValidate - * @uses PsrJwt\JwtParse + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Helper\Validate + * @uses PsrJwt\Helper\Parse * @uses PsrJwt\Parser\Body * @uses PsrJwt\Parser\Bearer * @uses PsrJwt\Parser\Server @@ -39,7 +39,7 @@ public function testJwtAuthHandler() */ public function testJwtAuthHandlerResponse() { - $jwt = JwtFactory::builder(); + $jwt = Jwt::builder(); $token = $jwt->setSecret('Secret123!456$') ->setIssuer('localhost') ->build() @@ -118,12 +118,12 @@ public function testGetSecret() /** * @covers PsrJwt\JwtAuthHandler::validate * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\JwtFactory - * @uses PsrJwt\JwtValidate + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Helper\Validate */ public function testValidate() { - $jwt = JwtFactory::builder(); + $jwt = Jwt::builder(); $token = $jwt->setSecret('Secret123!456$') ->setIssuer('localhost') ->build() @@ -142,12 +142,12 @@ public function testValidate() /** * @covers PsrJwt\JwtAuthHandler::validate * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\JwtFactory - * @uses PsrJwt\JwtValidate + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Helper\Validate */ public function testValidateBadSecret() { - $jwt = JwtFactory::builder(); + $jwt = Jwt::builder(); $token = $jwt->setSecret('Secret123!456$') ->setIssuer('localhost') ->build() @@ -166,12 +166,12 @@ public function testValidateBadSecret() /** * @covers PsrJwt\JwtAuthHandler::validate * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\JwtFactory - * @uses PsrJwt\JwtValidate + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Helper\Validate */ public function testValidateBadExpiration() { - $jwt = JwtFactory::builder(); + $jwt = Jwt::builder(); $token = $jwt->setSecret('Secret123!456$') ->setIssuer('localhost') ->setPayloadClaim('exp', time() - 10) @@ -191,12 +191,12 @@ public function testValidateBadExpiration() /** * @covers PsrJwt\JwtAuthHandler::validate * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\JwtFactory - * @uses PsrJwt\JwtValidate + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Helper\Validate */ public function testValidateBadNotBefore() { - $jwt = JwtFactory::builder(); + $jwt = Jwt::builder(); $token = $jwt->setSecret('Secret123!456$') ->setIssuer('localhost') ->setPayloadClaim('nbf', time() + 60) diff --git a/tests/JwtAuthInvokableTest.php b/tests/JwtAuthInvokableTest.php index 3e92c37..b7640c8 100644 --- a/tests/JwtAuthInvokableTest.php +++ b/tests/JwtAuthInvokableTest.php @@ -4,7 +4,7 @@ use PHPUnit\Framework\TestCase; use PsrJwt\JwtAuthInvokable; -use PsrJwt\JwtFactory; +use PsrJwt\Factory\Jwt; use PsrJwt\JwtAuthHandler; use PsrJwt\JwtAuthException; use Psr\Http\Message\ResponseInterface; @@ -32,14 +32,14 @@ public function testJwtAuthInokable() * @covers PsrJwt\JwtAuthInvokable::__invoke * @uses PsrJwt\JwtAuthInvokable::__construct * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\JwtFactory - * @uses PsrJwt\JwtValidate - * @uses PsrJwt\JwtParse + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Helper\Validate + * @uses PsrJwt\Helper\Parse * @uses PsrJwt\Parser\Bearer */ public function testInvoke() { - $jwt = JwtFactory::builder(); + $jwt = Jwt::builder(); $token = $jwt->setSecret('Secret123!456$') ->setIssuer('localhost') ->setPayloadClaim('nbf', time() - 60) @@ -71,9 +71,9 @@ public function testInvoke() * @covers PsrJwt\JwtAuthInvokable::__invoke * @uses PsrJwt\JwtAuthInvokable * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\JwtFactory - * @uses PsrJwt\JwtValidate - * @uses PsrJwt\JwtParse + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Helper\Validate + * @uses PsrJwt\Helper\Parse * @uses PsrJwt\Parser\Body * @uses PsrJwt\Parser\Bearer * @uses PsrJwt\Parser\Server diff --git a/tests/JwtAuthMiddlewareTest.php b/tests/JwtAuthMiddlewareTest.php index 09c1a7d..18a327a 100644 --- a/tests/JwtAuthMiddlewareTest.php +++ b/tests/JwtAuthMiddlewareTest.php @@ -3,7 +3,7 @@ namespace Tests; use PHPUnit\Framework\TestCase; -use PsrJwt\JwtFactory; +use PsrJwt\Factory\Jwt; use PsrJwt\JwtAuthMiddleware; use PsrJwt\JwtAuthHandler; use Psr\Http\Message\ResponseInterface; @@ -27,15 +27,15 @@ public function testJwtAuthProcess() /** * @covers PsrJwt\JwtAuthMiddleware::process - * @uses PsrJwt\JwtFactory + * @uses PsrJwt\Factory\Jwt * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\JwtParse - * @uses PsrJwt\JwtValidate + * @uses PsrJwt\Helper\Parse + * @uses PsrJwt\Helper\Validate * @uses PsrJwt\Parser\Bearer */ public function testProcess() { - $jwt = JwtFactory::builder(); + $jwt = Jwt::builder(); $token = $jwt->setSecret('Secret123!456$') ->setIssuer('localhost') ->setPayloadClaim('nbf', time() - 60) From d1fff0657a9e5bba10476ecdb031649be79b4d18 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Wed, 17 Apr 2019 16:38:36 +0100 Subject: [PATCH 03/22] Updated tests on Body parser to increase code coverage. --- tests/Parser/BodyTest.php | 103 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/tests/Parser/BodyTest.php b/tests/Parser/BodyTest.php index 21b88af..5c1ff59 100644 --- a/tests/Parser/BodyTest.php +++ b/tests/Parser/BodyTest.php @@ -7,6 +7,7 @@ use PsrJwt\Parser\ParserInterface; use Psr\Http\Message\ServerRequestInterface; use Mockery as m; +use ReflectionMethod; class BodyTest extends TestCase { @@ -38,6 +39,108 @@ public function testParse() $this->assertSame('abc.def.ghi', $result); } + /** + * @covers PsrJwt\Parser\Body::parse + * @uses PsrJwt\Parser\Body + */ + public function testParseObject() + { + $object = new \stdClass(); + $object->jwt = 'abc.def.ghi'; + + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getParsedBody') + ->twice() + ->andReturn($object); + + $body = new Body(['token_key' => 'jwt']); + $result = $body->parse($request); + + $this->assertSame('abc.def.ghi', $result); + } + + /** + * @covers PsrJwt\Parser\Body::parse + * @uses PsrJwt\Parser\Body + */ + public function testParseString() + { + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getParsedBody') + ->twice() + ->andReturn('hello'); + + $body = new Body(['token_key' => 'jwt']); + $result = $body->parse($request); + + $this->assertSame('', $result); + } + + /** + * @covers PsrJwt\Parser\Body::parseBodyObject + * @uses PsrJwt\Parser\Body::__construct + */ + public function testParseBodyObject() + { + $object = new \stdClass(); + $object->jwt = 'abc.def.ghi'; + + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getParsedBody') + ->once() + ->andReturn($object); + + $body = new Body(['token_key' => 'jwt']); + + $method = new ReflectionMethod(Body::class, 'parseBodyObject'); + $method->setAccessible(true); + $result = $method->invokeArgs($body, [$request]); + + $this->assertSame('abc.def.ghi', $result); + } + + /** + * @covers PsrJwt\Parser\Body::parseBodyObject + * @uses PsrJwt\Parser\Body::__construct + */ + public function testParseBodyObjectNoKey() + { + $object = new \stdClass(); + + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getParsedBody') + ->once() + ->andReturn($object); + + $body = new Body(['token_key' => 'jwt']); + + $method = new ReflectionMethod(Body::class, 'parseBodyObject'); + $method->setAccessible(true); + $result = $method->invokeArgs($body, [$request]); + + $this->assertSame('', $result); + } + + /** + * @covers PsrJwt\Parser\Body::parseBodyObject + * @uses PsrJwt\Parser\Body::__construct + */ + public function testParseBodyObjectNoObject() + { + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getParsedBody') + ->once() + ->andReturn([]); + + $body = new Body(['token_key' => 'jwt']); + + $method = new ReflectionMethod(Body::class, 'parseBodyObject'); + $method->setAccessible(true); + $result = $method->invokeArgs($body, [$request]); + + $this->assertSame('', $result); + } + public function tearDown() { m::close(); From d8d4a389cd7d8c0c7f1084114ff0bef1310ec88f Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Thu, 18 Apr 2019 08:22:13 +0100 Subject: [PATCH 04/22] Added more tests for getToken method in JwtAuthHandler class. --- src/JwtAuthHandler.php | 6 ++-- tests/JwtAuthHandlerTest.php | 63 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/JwtAuthHandler.php b/src/JwtAuthHandler.php index e8584e4..03ce3a6 100644 --- a/src/JwtAuthHandler.php +++ b/src/JwtAuthHandler.php @@ -27,12 +27,12 @@ public function __construct(string $tokenKey, string $secret) $this->secret = $secret; } - protected function getSecret(): string + public function getSecret(): string { return $this->secret; } - protected function validate(string $token): ResponseInterface + private function validate(string $token): ResponseInterface { $parse = Jwt::parser($token, $this->getSecret()); @@ -64,7 +64,7 @@ private function hasJwt(string $token): bool return !empty($token); } - protected function getToken(ServerRequestInterface $request): string + private function getToken(ServerRequestInterface $request): string { $parse = new Parse(['token_key' => $this->tokenKey]); $parse->addParser(\PsrJwt\Parser\Bearer::class); diff --git a/tests/JwtAuthHandlerTest.php b/tests/JwtAuthHandlerTest.php index 4dace5c..3dc41ea 100644 --- a/tests/JwtAuthHandlerTest.php +++ b/tests/JwtAuthHandlerTest.php @@ -258,6 +258,69 @@ public function testValidationResponseErrors() } } + /** + * @covers PsrJwt\JwtAuthHandler::getToken + * @uses PsrJwt\JwtAuthHandler + * @uses PsrJwt\Helper\Parse + * @uses PsrJwt\Parser\Bearer + */ + public function testGetToken() + { + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getHeader') + ->with('authorization') + ->once() + ->andReturn(['Bearer abc.def.ghi']); + + $handler = new JwtAuthHandler('jwt', 'secret'); + + $method = new ReflectionMethod(JwtAuthHandler::class, 'getToken'); + $method->setAccessible(true); + $result = $method->invokeArgs($handler, [$request]); + + $this->assertSame('abc.def.ghi', $result); + } + + /** + * @expectedException ReallySimpleJWT\Exception\ValidateException + * @expectedExceptionMessage JSON Web Token not set. + * @expectedExceptionCode 11 + * @covers PsrJwt\JwtAuthHandler::getToken + * @uses PsrJwt\JwtAuthHandler + * @uses PsrJwt\Helper\Parse + * @uses PsrJwt\Parser\Bearer + * @uses PsrJwt\Parser\Server + * @uses PsrJwt\Parser\Body + * @uses PsrJwt\Parser\Cookie + * @uses PsrJwt\Parser\Query + */ + public function testGetTokenNoToken() + { + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getHeader') + ->with('authorization') + ->once() + ->andReturn([]); + $request->shouldReceive('getServerParams') + ->once() + ->andReturn([]); + $request->shouldReceive('getCookieParams') + ->once() + ->andReturn([]); + $request->shouldReceive('getQueryParams') + ->once() + ->andReturn([]); + $request->shouldReceive('getParsedBody') + ->twice() + ->andReturn([]); + + $handler = new JwtAuthHandler('jwt', 'secret'); + + $method = new ReflectionMethod(JwtAuthHandler::class, 'getToken'); + $method->setAccessible(true); + $result = $method->invokeArgs($handler, [$request]); + } + public function tearDown() { m::close(); } From 1a4ac38e5f8f4a21aa7486fc1f2af8e49cc55cec Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Thu, 18 Apr 2019 12:53:13 +0100 Subject: [PATCH 05/22] Added test to check handle method in Handler class fails as expected. --- tests/JwtAuthHandlerTest.php | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/JwtAuthHandlerTest.php b/tests/JwtAuthHandlerTest.php index 3dc41ea..1a5c192 100644 --- a/tests/JwtAuthHandlerTest.php +++ b/tests/JwtAuthHandlerTest.php @@ -68,6 +68,50 @@ public function testJwtAuthHandlerResponse() $result = $handler->handle($request); $this->assertInstanceOf(ResponseInterface::class, $result); + $this->assertSame(200, $result->getStatusCode()); + $this->assertSame('Ok', $result->getReasonPhrase()); + } + + /** + * @covers PsrJwt\JwtAuthHandler::handle + * @uses PsrJwt\JwtAuthHandler + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Helper\Validate + * @uses PsrJwt\Helper\Parse + * @uses PsrJwt\Parser\Body + * @uses PsrJwt\Parser\Bearer + * @uses PsrJwt\Parser\Server + * @uses PsrJwt\Parser\Query + * @uses PsrJwt\Parser\Cookie + */ + public function testJwtAuthHandlerResponseBadRequest() + { + $jwt = Jwt::builder(); + + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getServerParams') + ->once() + ->andReturn([]); + $request->shouldReceive('getCookieParams') + ->once() + ->andReturn(['foo' => 'bar']); + $request->shouldReceive('getQueryParams') + ->once() + ->andReturn(['hello' => 'world']); + $request->shouldReceive('getParsedBody') + ->twice() + ->andReturn([]); + $request->shouldReceive('getHeader') + ->with('authorization') + ->once() + ->andReturn([]); + + $handler = new JwtAuthHandler('jwt', 'Secret123!456$'); + + $result = $handler->handle($request); + + $this->assertSame(400, $result->getStatusCode()); + $this->assertSame('Bad Request: JSON Web Token not set.', $result->getReasonPhrase()); } /** From 676afdd810fbbddc51135ff28f3cd718e61a2ba8 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Thu, 18 Apr 2019 13:18:21 +0100 Subject: [PATCH 06/22] Added futher tests to Parse and Valdidate classes to reach 100% coverage. --- src/Helper/Parse.php | 7 ++++- tests/Helper/ParseTest.php | 34 +++++++++++++++++++++++ tests/Helper/ValidateTest.php | 52 ++++++++++++++++++++++++++++++++++- 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/Helper/Parse.php b/src/Helper/Parse.php index 344fff1..d846ca8 100644 --- a/src/Helper/Parse.php +++ b/src/Helper/Parse.php @@ -22,9 +22,14 @@ public function addParser(string $parser): void $this->parsers[] = $parser; } + public function getParsers(): array + { + return $this->parsers; + } + public function findToken(ServerRequestInterface $request): string { - foreach ($this->parsers as $parser) { + foreach ($this->getParsers() as $parser) { $object = new $parser($this->arguments); $token = $object->parse($request); if (!empty($token)) { diff --git a/tests/Helper/ParseTest.php b/tests/Helper/ParseTest.php index 514892d..27856fb 100644 --- a/tests/Helper/ParseTest.php +++ b/tests/Helper/ParseTest.php @@ -6,6 +6,7 @@ use PsrJwt\Helper\Parse; use Psr\Http\Message\ServerRequestInterface; use PsrJwt\Parser\Bearer; +use PsrJwt\Parser\Cookie; use ReflectionMethod; use Mockery as m; use stdClass; @@ -42,6 +43,39 @@ public function testFindToken() $this->assertSame('abc.def.ghi', $result); } + /** + * @covers PsrJwt\Helper\Parse::addParser + * @covers PsrJwt\Helper\Parse::getParsers + * @uses PsrJwt\Helper\Parse + */ + public function testAddParser() + { + $parse = new Parse(['token_key' => 'jwt']); + $parse->addParser(Bearer::class); + $parse->addParser(Cookie::class); + + $result = $parse->getParsers(); + + $this->assertCount(2, $result); + $this->assertSame(Bearer::class, $result[0]); + $this->assertSame(Cookie::class, $result[1]); + } + + /** + * @covers PsrJwt\Helper\Parse::addParser + * @covers PsrJwt\Helper\Parse::getParsers + * @uses PsrJwt\Helper\Parse + */ + public function testFindTokenFail() + { + $request = m::mock(ServerRequestInterface::class); + + $parse = new Parse(['token_key' => 'jwt']); + $result = $parse->findToken($request); + + $this->assertEmpty($result); + } + public function tearDown() { m::close(); } diff --git a/tests/Helper/ValidateTest.php b/tests/Helper/ValidateTest.php index 321ef35..3963f92 100644 --- a/tests/Helper/ValidateTest.php +++ b/tests/Helper/ValidateTest.php @@ -34,7 +34,31 @@ public function testValidate() * @uses PsrJwt\Helper\Validate * @uses PsrJwt\Factory\Jwt */ - public function testValidateTrue() + public function testValidateOk() + { + $jwt = Jwt::builder(); + $token = $jwt->setSecret('Secret123!456$') + ->setIssuer('localhost') + ->setPayloadClaim('exp', time() + 10) + ->build() + ->getToken(); + + $validate = new Validate( + Jwt::parser($token, 'Secret123!456$') + ); + + $result = $validate->validate(); + + $this->assertSame(0, $result['code']); + $this->assertSame('Ok', $result['message']); + } + + /** + * @covers PsrJwt\Helper\Validate::validate + * @uses PsrJwt\Helper\Validate + * @uses PsrJwt\Factory\Jwt + */ + public function testValidateExpiration() { $jwt = Jwt::builder(); $token = $jwt->setSecret('Secret123!456$') @@ -78,4 +102,30 @@ public function testValidateNotBefore() $this->assertSame(5, $result['code']); $this->assertSame('Not Before claim has not elapsed.', $result['message']); } + + /** + * @covers PsrJwt\Helper\Validate::validateNotBefore + * @uses PsrJwt\Helper\Validate + * @uses PsrJwt\Factory\Jwt + */ + public function testValidateNotBeforeOk() + { + $jwt = Jwt::builder(); + $token = $jwt->setSecret('Secret123!456$') + ->setIssuer('localhost') + ->setPayloadClaim('nbf', time() - 20) + ->build() + ->getToken(); + + $validate = new Validate( + Jwt::parser($token, 'Secret123!456$') + ); + + $result = $validate->validateNotBefore( + ['code' => 0, 'message' => 'Ok'] + ); + + $this->assertSame(0, $result['code']); + $this->assertSame('Ok', $result['message']); + } } From 45d9b8e12c56a954d2ab674feb2cd70913cc4327 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Thu, 18 Apr 2019 13:40:47 +0100 Subject: [PATCH 07/22] Made namespace structure of Parser and Validation class more logical as helper namespace made no sense at all. --- src/JwtAuthHandler.php | 4 ++-- src/{Helper => Parser}/Parse.php | 2 +- src/{Helper => Validation}/Validate.php | 2 +- tests/JwtAuthHandlerTest.php | 20 ++++++++--------- tests/JwtAuthInvokableTest.php | 8 +++---- tests/JwtAuthMiddlewareTest.php | 4 ++-- tests/{Helper => Parser}/ParseTest.php | 22 +++++++++---------- tests/{Helper => Validation}/ValidateTest.php | 22 +++++++++---------- 8 files changed, 42 insertions(+), 42 deletions(-) rename src/{Helper => Parser}/Parse.php (96%) rename src/{Helper => Validation}/Validate.php (97%) rename tests/{Helper => Parser}/ParseTest.php (79%) rename tests/{Helper => Validation}/ValidateTest.php (85%) diff --git a/src/JwtAuthHandler.php b/src/JwtAuthHandler.php index 03ce3a6..61aa9b5 100644 --- a/src/JwtAuthHandler.php +++ b/src/JwtAuthHandler.php @@ -5,8 +5,8 @@ namespace PsrJwt; use PsrJwt\Factory\Jwt; -use PsrJwt\Helper\Validate; -use PsrJwt\Helper\Parse; +use PsrJwt\Validation\Validate; +use PsrJwt\Parser\Parse; use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; diff --git a/src/Helper/Parse.php b/src/Parser/Parse.php similarity index 96% rename from src/Helper/Parse.php rename to src/Parser/Parse.php index d846ca8..f1d52bf 100644 --- a/src/Helper/Parse.php +++ b/src/Parser/Parse.php @@ -2,7 +2,7 @@ declare(strict_types = 1); -namespace PsrJwt\Helper; +namespace PsrJwt\Parser; use Psr\Http\Message\ServerRequestInterface; diff --git a/src/Helper/Validate.php b/src/Validation/Validate.php similarity index 97% rename from src/Helper/Validate.php rename to src/Validation/Validate.php index 734fe2d..a2b0f5f 100644 --- a/src/Helper/Validate.php +++ b/src/Validation/Validate.php @@ -2,7 +2,7 @@ declare(strict_types = 1); -namespace PsrJwt\Helper; +namespace PsrJwt\Validation; use ReallySimpleJWT\Parse; use ReallySimpleJWT\Exception\ValidateException; diff --git a/tests/JwtAuthHandlerTest.php b/tests/JwtAuthHandlerTest.php index 1a5c192..6b4fab4 100644 --- a/tests/JwtAuthHandlerTest.php +++ b/tests/JwtAuthHandlerTest.php @@ -29,8 +29,8 @@ public function testJwtAuthHandler() * @covers PsrJwt\JwtAuthHandler::handle * @uses PsrJwt\JwtAuthHandler * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Helper\Validate - * @uses PsrJwt\Helper\Parse + * @uses PsrJwt\Validation\Validate + * @uses PsrJwt\Parser\Parse * @uses PsrJwt\Parser\Body * @uses PsrJwt\Parser\Bearer * @uses PsrJwt\Parser\Server @@ -76,8 +76,8 @@ public function testJwtAuthHandlerResponse() * @covers PsrJwt\JwtAuthHandler::handle * @uses PsrJwt\JwtAuthHandler * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Helper\Validate - * @uses PsrJwt\Helper\Parse + * @uses PsrJwt\Validation\Validate + * @uses PsrJwt\Parser\Parse * @uses PsrJwt\Parser\Body * @uses PsrJwt\Parser\Bearer * @uses PsrJwt\Parser\Server @@ -163,7 +163,7 @@ public function testGetSecret() * @covers PsrJwt\JwtAuthHandler::validate * @uses PsrJwt\JwtAuthHandler * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Helper\Validate + * @uses PsrJwt\Validation\Validate */ public function testValidate() { @@ -187,7 +187,7 @@ public function testValidate() * @covers PsrJwt\JwtAuthHandler::validate * @uses PsrJwt\JwtAuthHandler * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Helper\Validate + * @uses PsrJwt\Validation\Validate */ public function testValidateBadSecret() { @@ -211,7 +211,7 @@ public function testValidateBadSecret() * @covers PsrJwt\JwtAuthHandler::validate * @uses PsrJwt\JwtAuthHandler * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Helper\Validate + * @uses PsrJwt\Validation\Validate */ public function testValidateBadExpiration() { @@ -236,7 +236,7 @@ public function testValidateBadExpiration() * @covers PsrJwt\JwtAuthHandler::validate * @uses PsrJwt\JwtAuthHandler * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Helper\Validate + * @uses PsrJwt\Validation\Validate */ public function testValidateBadNotBefore() { @@ -305,7 +305,7 @@ public function testValidationResponseErrors() /** * @covers PsrJwt\JwtAuthHandler::getToken * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\Helper\Parse + * @uses PsrJwt\Parser\Parse * @uses PsrJwt\Parser\Bearer */ public function testGetToken() @@ -331,7 +331,7 @@ public function testGetToken() * @expectedExceptionCode 11 * @covers PsrJwt\JwtAuthHandler::getToken * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\Helper\Parse + * @uses PsrJwt\Parser\Parse * @uses PsrJwt\Parser\Bearer * @uses PsrJwt\Parser\Server * @uses PsrJwt\Parser\Body diff --git a/tests/JwtAuthInvokableTest.php b/tests/JwtAuthInvokableTest.php index b7640c8..57bf962 100644 --- a/tests/JwtAuthInvokableTest.php +++ b/tests/JwtAuthInvokableTest.php @@ -33,8 +33,8 @@ public function testJwtAuthInokable() * @uses PsrJwt\JwtAuthInvokable::__construct * @uses PsrJwt\JwtAuthHandler * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Helper\Validate - * @uses PsrJwt\Helper\Parse + * @uses PsrJwt\Validation\Validate + * @uses PsrJwt\Parser\Parse * @uses PsrJwt\Parser\Bearer */ public function testInvoke() @@ -72,8 +72,8 @@ public function testInvoke() * @uses PsrJwt\JwtAuthInvokable * @uses PsrJwt\JwtAuthHandler * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Helper\Validate - * @uses PsrJwt\Helper\Parse + * @uses PsrJwt\Validation\Validate + * @uses PsrJwt\Parser\Parse * @uses PsrJwt\Parser\Body * @uses PsrJwt\Parser\Bearer * @uses PsrJwt\Parser\Server diff --git a/tests/JwtAuthMiddlewareTest.php b/tests/JwtAuthMiddlewareTest.php index 18a327a..a253430 100644 --- a/tests/JwtAuthMiddlewareTest.php +++ b/tests/JwtAuthMiddlewareTest.php @@ -29,8 +29,8 @@ public function testJwtAuthProcess() * @covers PsrJwt\JwtAuthMiddleware::process * @uses PsrJwt\Factory\Jwt * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\Helper\Parse - * @uses PsrJwt\Helper\Validate + * @uses PsrJwt\Parser\Parse + * @uses PsrJwt\Validation\Validate * @uses PsrJwt\Parser\Bearer */ public function testProcess() diff --git a/tests/Helper/ParseTest.php b/tests/Parser/ParseTest.php similarity index 79% rename from tests/Helper/ParseTest.php rename to tests/Parser/ParseTest.php index 27856fb..b33b83b 100644 --- a/tests/Helper/ParseTest.php +++ b/tests/Parser/ParseTest.php @@ -1,9 +1,9 @@ Date: Thu, 18 Apr 2019 13:50:42 +0100 Subject: [PATCH 08/22] Fixed issue in ParseTest so coverage is correct and 100% is achieved. --- tests/Parser/ParseTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/Parser/ParseTest.php b/tests/Parser/ParseTest.php index b33b83b..ad08967 100644 --- a/tests/Parser/ParseTest.php +++ b/tests/Parser/ParseTest.php @@ -62,8 +62,7 @@ public function testAddParser() } /** - * @covers PsrJwt\Parser\Parse::addParser - * @covers PsrJwt\Parser\Parse::getParsers + * @covers PsrJwt\Parser\Parse::findToken * @uses PsrJwt\Parser\Parse */ public function testFindTokenFail() From 7f6dc994d6e7b2ac2b7b55a9fce01e2c4a910611 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Thu, 18 Apr 2019 14:04:53 +0100 Subject: [PATCH 09/22] Fixed issues with tests raised by phpstan which are not mockery related. --- tests/Factory/JwtAuthTest.php | 2 +- tests/Factory/JwtTest.php | 2 +- tests/JwtAuthHandlerTest.php | 2 +- tests/JwtAuthMiddlewareTest.php | 2 +- tests/Parser/BearerTest.php | 2 +- tests/Parser/BodyTest.php | 2 +- tests/Parser/CookieTest.php | 2 +- tests/Parser/QueryTest.php | 2 +- tests/Parser/ServerTest.php | 2 +- tests/Validation/ValidateTest.php | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/Factory/JwtAuthTest.php b/tests/Factory/JwtAuthTest.php index 2f16a12..2569bfa 100644 --- a/tests/Factory/JwtAuthTest.php +++ b/tests/Factory/JwtAuthTest.php @@ -1,6 +1,6 @@ assertInstanceOf(JwtAuthMiddleware::class, $process); $this->assertInstanceOf(MiddlewareInterface::class, $process); diff --git a/tests/Parser/BearerTest.php b/tests/Parser/BearerTest.php index d593b36..93d3150 100644 --- a/tests/Parser/BearerTest.php +++ b/tests/Parser/BearerTest.php @@ -1,6 +1,6 @@ Date: Sun, 28 Apr 2019 10:47:31 +0100 Subject: [PATCH 10/22] Create auth namespace with two initial classes with tests. --- src/Auth/Auth.php | 19 +++++++++++++++++++ src/Auth/Authenticate.php | 19 +++++++++++++++++++ tests/Auth/AuthTest.php | 15 +++++++++++++++ tests/Auth/AuthenticateTest.php | 15 +++++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 src/Auth/Auth.php create mode 100644 src/Auth/Authenticate.php create mode 100644 tests/Auth/AuthTest.php create mode 100644 tests/Auth/AuthenticateTest.php diff --git a/src/Auth/Auth.php b/src/Auth/Auth.php new file mode 100644 index 0000000..425b383 --- /dev/null +++ b/src/Auth/Auth.php @@ -0,0 +1,19 @@ +code = $code; + + $this->message = $message; + } +} diff --git a/src/Auth/Authenticate.php b/src/Auth/Authenticate.php new file mode 100644 index 0000000..15aa292 --- /dev/null +++ b/src/Auth/Authenticate.php @@ -0,0 +1,19 @@ +tokenKey = $tokenKey; + + $this->secret = $secret; + } +} diff --git a/tests/Auth/AuthTest.php b/tests/Auth/AuthTest.php new file mode 100644 index 0000000..bd2032f --- /dev/null +++ b/tests/Auth/AuthTest.php @@ -0,0 +1,15 @@ +assertInstanceOf(Auth::class, $auth); + } +} diff --git a/tests/Auth/AuthenticateTest.php b/tests/Auth/AuthenticateTest.php new file mode 100644 index 0000000..cb889d8 --- /dev/null +++ b/tests/Auth/AuthenticateTest.php @@ -0,0 +1,15 @@ +assertInstanceOf(Authenticate::class, $auth); + } +} From ebfec293e22e687e1a64f9c008c415f49f491f97 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Sun, 28 Apr 2019 10:52:57 +0100 Subject: [PATCH 11/22] Finished writing auth class and associated tests. --- src/Auth/Auth.php | 10 ++++++++++ tests/Auth/AuthTest.php | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/Auth/Auth.php b/src/Auth/Auth.php index 425b383..82aa10a 100644 --- a/src/Auth/Auth.php +++ b/src/Auth/Auth.php @@ -16,4 +16,14 @@ public function __construct(int $code, string $message) $this->message = $message; } + + public function getCode(): int + { + return $this->code; + } + + public function getMessage(): string + { + return $this->message; + } } diff --git a/tests/Auth/AuthTest.php b/tests/Auth/AuthTest.php index bd2032f..86716f8 100644 --- a/tests/Auth/AuthTest.php +++ b/tests/Auth/AuthTest.php @@ -11,5 +11,22 @@ public function testAuth() { $auth = new Auth(200, 'Ok'); $this->assertInstanceOf(Auth::class, $auth); + return $auth; + } + + /** + * @depends testAuth + */ + public function testGetCode($auth) + { + $this->assertSame(200, $auth->getCode()); + } + + /** + * @depends testAuth + */ + public function testGetMessage($auth) + { + $this->assertSame('Ok', $auth->getMessage()); } } From 93583a02492668246808b09c20de5a56352f6123 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Sun, 28 Apr 2019 11:09:33 +0100 Subject: [PATCH 12/22] Added authenticate method to Authenticate class and finished writing tests. --- src/Auth/Authenticate.php | 70 +++++++++++++++++++++++++++++++++ tests/Auth/AuthenticateTest.php | 56 ++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/src/Auth/Authenticate.php b/src/Auth/Authenticate.php index 15aa292..8d3de2c 100644 --- a/src/Auth/Authenticate.php +++ b/src/Auth/Authenticate.php @@ -4,6 +4,12 @@ namespace PsrJwt\Auth; +use Psr\Http\Message\ServerRequestInterface; +use PsrJwt\Factory\Jwt; +use PsrJwt\Auth\Auth; +use PsrJwt\Parser\Parse; +use PsrJwt\Validation\Validate; + class Authenticate { private $tokenKey; @@ -16,4 +22,68 @@ public function __construct(string $tokenKey, string $secret) $this->secret = $secret; } + + public function authenticate(ServerRequestInterface $request): Auth + { + try { + $token = $this->getToken($request); + } catch (ValidateException $e) { + return new Auth(400, 'Bad Request: ' . $e->getMessage()); + } + + return $this->validate($token); + } + + public function getSecret(): string + { + return $this->secret; + } + + private function validate(string $token): Auth + { + $parse = Jwt::parser($token, $this->getSecret()); + + $validate = new Validate($parse); + + $validationState = $validate->validate(); + + $validationState = $validate->validateNotBefore($validationState); + + return $this->validationResponse( + $validationState['code'], + $validationState['message'] + ); + } + + private function validationResponse(int $code, string $message): Auth + { + if (in_array($code, [1, 2, 3, 4, 5], true)) { + return new Auth(401, 'Unauthorized: ' . $message); + } + + return new Auth(200, 'Ok'); + } + + private function hasJwt(string $token): bool + { + return !empty($token); + } + + private function getToken(ServerRequestInterface $request): string + { + $parse = new Parse(['token_key' => $this->tokenKey]); + $parse->addParser(\PsrJwt\Parser\Bearer::class); + $parse->addParser(\PsrJwt\Parser\Cookie::class); + $parse->addParser(\PsrJwt\Parser\Body::class); + $parse->addParser(\PsrJwt\Parser\Query::class); + $parse->addParser(\PsrJwt\Parser\Server::class); + + $token = $parse->findToken($request); + + if ($this->hasJwt($token)) { + return $token; + } + + throw new ValidateException('JSON Web Token not set.', 11); + } } diff --git a/tests/Auth/AuthenticateTest.php b/tests/Auth/AuthenticateTest.php index cb889d8..353c38e 100644 --- a/tests/Auth/AuthenticateTest.php +++ b/tests/Auth/AuthenticateTest.php @@ -3,7 +3,11 @@ namespace Tests\Auth; use PHPUnit\Framework\TestCase; +use Psr\Http\Message\ServerRequestInterface; use PsrJwt\Auth\Authenticate; +use PsrJwt\Auth\Auth; +use PsrJwt\Factory\Jwt; +use Mockery as m; class AuthenticateTest extends TestCase { @@ -12,4 +16,56 @@ public function testAuthenticate() $auth = new Authenticate('jwt', 'secret'); $this->assertInstanceOf(Authenticate::class, $auth); } + + /** + * @covers PsrJwt\JwtAuthHandler::handle + * @uses PsrJwt\JwtAuthHandler + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Validation\Validate + * @uses PsrJwt\Parser\Parse + * @uses PsrJwt\Parser\Body + * @uses PsrJwt\Parser\Bearer + * @uses PsrJwt\Parser\Server + * @uses PsrJwt\Parser\Query + * @uses PsrJwt\Parser\Cookie + */ + public function testAuthenticateOk() + { + $jwt = Jwt::builder(); + $token = $jwt->setSecret('Secret123!456$') + ->setIssuer('localhost') + ->build() + ->getToken(); + + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getServerParams') + ->once() + ->andReturn(['jwt' => $token]); + $request->shouldReceive('getCookieParams') + ->once() + ->andReturn(['foo' => 'bar']); + $request->shouldReceive('getQueryParams') + ->once() + ->andReturn(['hello' => 'world']); + $request->shouldReceive('getParsedBody') + ->twice() + ->andReturn([]); + $request->shouldReceive('getHeader') + ->with('authorization') + ->once() + ->andReturn([]); + + $authenticate = new Authenticate('jwt', 'Secret123!456$'); + + $result = $authenticate->authenticate($request); + + $this->assertInstanceOf(Auth::class, $result); + $this->assertSame(200, $result->getCode()); + $this->assertSame('Ok', $result->getMessage()); + } + + public function tearDown() + { + m::close(); + } } From 22cbd1a1ad56cb83bc7b2b6939271ee3080628c4 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Sun, 28 Apr 2019 11:27:23 +0100 Subject: [PATCH 13/22] Transfered JwtAuthHandler tests to Authentication class tests as JwtAuthHandler is being replaced. --- src/Auth/Authenticate.php | 1 + tests/Auth/AuthenticateTest.php | 298 +++++++++++++++++++++++++++++++- 2 files changed, 297 insertions(+), 2 deletions(-) diff --git a/src/Auth/Authenticate.php b/src/Auth/Authenticate.php index 8d3de2c..b8e8fe1 100644 --- a/src/Auth/Authenticate.php +++ b/src/Auth/Authenticate.php @@ -5,6 +5,7 @@ namespace PsrJwt\Auth; use Psr\Http\Message\ServerRequestInterface; +use ReallySimpleJWT\Exception\ValidateException; use PsrJwt\Factory\Jwt; use PsrJwt\Auth\Auth; use PsrJwt\Parser\Parse; diff --git a/tests/Auth/AuthenticateTest.php b/tests/Auth/AuthenticateTest.php index 353c38e..48eb4a6 100644 --- a/tests/Auth/AuthenticateTest.php +++ b/tests/Auth/AuthenticateTest.php @@ -7,6 +7,7 @@ use PsrJwt\Auth\Authenticate; use PsrJwt\Auth\Auth; use PsrJwt\Factory\Jwt; +use ReflectionMethod; use Mockery as m; class AuthenticateTest extends TestCase @@ -18,8 +19,8 @@ public function testAuthenticate() } /** - * @covers PsrJwt\JwtAuthHandler::handle - * @uses PsrJwt\JwtAuthHandler + * @covers PsrJwt\Auth\Authenticate::handle + * @uses PsrJwt\Auth\Authenticate * @uses PsrJwt\Factory\Jwt * @uses PsrJwt\Validation\Validate * @uses PsrJwt\Parser\Parse @@ -64,6 +65,299 @@ public function testAuthenticateOk() $this->assertSame('Ok', $result->getMessage()); } + /** + * @covers PsrJwt\Auth\Authenticate::handle + * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Validation\Validate + * @uses PsrJwt\Parser\Parse + * @uses PsrJwt\Parser\Body + * @uses PsrJwt\Parser\Bearer + * @uses PsrJwt\Parser\Server + * @uses PsrJwt\Parser\Query + * @uses PsrJwt\Parser\Cookie + */ + public function testAuthenticateBadRequest() + { + $jwt = Jwt::builder(); + + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getServerParams') + ->once() + ->andReturn([]); + $request->shouldReceive('getCookieParams') + ->once() + ->andReturn(['foo' => 'bar']); + $request->shouldReceive('getQueryParams') + ->once() + ->andReturn(['hello' => 'world']); + $request->shouldReceive('getParsedBody') + ->twice() + ->andReturn([]); + $request->shouldReceive('getHeader') + ->with('authorization') + ->once() + ->andReturn([]); + + $auth = new Authenticate('jwt', 'Secret123!456$'); + + $result = $auth->authenticate($request); + + $this->assertSame(400, $result->getCode()); + $this->assertSame('Bad Request: JSON Web Token not set.', $result->getMessage()); + } + + /** + * @covers PsrJwt\Auth\Authenticate::hasJwt + * @uses PsrJwt\Auth\Authenticate::__construct + */ + public function testAuthenticateHasJwt() + { + $auth = new Authenticate('jwt', 'secret'); + + $method = new ReflectionMethod(Authenticate::class, 'hasJwt'); + $method->setAccessible(true); + $result = $method->invokeArgs($auth, ['abc.abc.abc']); + + $this->assertTrue($result); + } + + /** + * @covers PsrJwt\Auth\Authenticate::hasJwt + * @uses PsrJwt\Auth\Authenticate::__construct + */ + public function testAuthenticateHasJwtEmpty() + { + $auth = new Authenticate('jwt', 'secret'); + + $method = new ReflectionMethod(Authenticate::class, 'hasJwt'); + $method->setAccessible(true); + $result = $method->invokeArgs($auth, ['']); + + $this->assertFalse($result); + } + + /** + * @covers PsrJwt\Auth\Authenticate::getSecret + * @uses PsrJwt\Auth\Authenticate::__construct + */ + public function testGetSecret() + { + $auth = new Authenticate('jwt', 'secret'); + + $method = new ReflectionMethod(Authenticate::class, 'getSecret'); + $method->setAccessible(true); + $result = $method->invoke($auth); + + $this->assertSame('secret', $result); + } + + /** + * @covers PsrJwt\Auth\Authenticate::validate + * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Validation\Validate + */ + public function testValidate() + { + $jwt = Jwt::builder(); + $token = $jwt->setSecret('Secret123!456$') + ->setIssuer('localhost') + ->build() + ->getToken(); + + $auth = new Authenticate('jwt', 'Secret123!456$'); + + $method = new ReflectionMethod(Authenticate::class, 'validate'); + $method->setAccessible(true); + $result = $method->invokeArgs($auth, [$token]); + + $this->assertSame(200, $result->getCode()); + $this->assertSame('Ok', $result->getMessage()); + } + + /** + * @covers PsrJwt\Auth\Authenticate::validate + * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Validation\Validate + */ + public function testValidateBadSecret() + { + $jwt = Jwt::builder(); + $token = $jwt->setSecret('Secret123!456$') + ->setIssuer('localhost') + ->build() + ->getToken(); + + $auth = new Authenticate('jwt', 'Secret'); + + $method = new ReflectionMethod(Authenticate::class, 'validate'); + $method->setAccessible(true); + $result = $method->invokeArgs($auth, [$token]); + + $this->assertSame(401, $result->getCode()); + $this->assertSame('Unauthorized: Signature is invalid.', $result->getMessage()); + } + + /** + * @covers PsrJwt\Auth\Authenticate::validate + * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Validation\Validate + */ + public function testValidateBadExpiration() + { + $jwt = Jwt::builder(); + $token = $jwt->setSecret('Secret123!456$') + ->setIssuer('localhost') + ->setPayloadClaim('exp', time() - 10) + ->build() + ->getToken(); + + $auth = new Authenticate('jwt', 'Secret123!456$'); + + $method = new ReflectionMethod(Authenticate::class, 'validate'); + $method->setAccessible(true); + $result = $method->invokeArgs($auth, [$token]); + + $this->assertSame(401, $result->getCode()); + $this->assertSame('Unauthorized: Expiration claim has expired.', $result->getMessage()); + } + + /** + * @covers PsrJwt\Auth\Authenticate::validate + * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Validation\Validate + */ + public function testValidateBadNotBefore() + { + $jwt = Jwt::builder(); + $token = $jwt->setSecret('Secret123!456$') + ->setIssuer('localhost') + ->setPayloadClaim('nbf', time() + 60) + ->build() + ->getToken(); + + $auth = new Authenticate('jwt', 'Secret123!456$'); + + $method = new ReflectionMethod(Authenticate::class, 'validate'); + $method->setAccessible(true); + $result = $method->invokeArgs($auth, [$token]); + + $this->assertSame(401, $result->getCode()); + $this->assertSame('Unauthorized: Not Before claim has not elapsed.', $result->getMessage()); + } + + /** + * @covers PsrJwt\Auth\Authenticate::validationResponse + * @uses PsrJwt\Auth\Authenticate::__construct + */ + public function testValidationResponse() + { + $auth = new Authenticate('jwt', 'secret'); + + $method = new ReflectionMethod(Authenticate::class, 'validationResponse'); + $method->setAccessible(true); + $result = $method->invokeArgs($auth, [0, 'Ok']); + + $this->assertInstanceOf(Auth::class, $result); + $this->assertSame(200, $result->getCode()); + $this->assertSame('Ok', $result->getMessage()); + } + + /** + * @covers PsrJwt\Auth\Authenticate::validationResponse + * @uses PsrJwt\Auth\Authenticate::__construct + */ + public function testValidationResponseErrors() + { + $auth = new Authenticate('jwt', 'secret'); + + $method = new ReflectionMethod(Authenticate::class, 'validationResponse'); + $method->setAccessible(true); + + $errors = [ + [1, 'Error 1'], + [2, 'Error 1'], + [3, 'Error 1'], + [4, 'Error 1'], + [5, 'Error 1'] + ]; + + foreach ($errors as $error) { + $result = $method->invokeArgs($auth, [$error[0], $error[1]]); + + $this->assertInstanceOf(Auth::class, $result); + $this->assertSame(401, $result->getCode()); + $this->assertSame('Unauthorized: ' . $error[1], $result->getMessage()); + } + } + + /** + * @covers PsrJwt\Auth\Authenticate::getToken + * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Parser\Parse + * @uses PsrJwt\Parser\Bearer + */ + public function testGetToken() + { + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getHeader') + ->with('authorization') + ->once() + ->andReturn(['Bearer abc.def.ghi']); + + $auth = new Authenticate('jwt', 'secret'); + + $method = new ReflectionMethod(Authenticate::class, 'getToken'); + $method->setAccessible(true); + $result = $method->invokeArgs($auth, [$request]); + + $this->assertSame('abc.def.ghi', $result); + } + + /** + * @expectedException ReallySimpleJWT\Exception\ValidateException + * @expectedExceptionMessage JSON Web Token not set. + * @expectedExceptionCode 11 + * @covers PsrJwt\Auth\Authenticate::getToken + * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Parser\Parse + * @uses PsrJwt\Parser\Bearer + * @uses PsrJwt\Parser\Server + * @uses PsrJwt\Parser\Body + * @uses PsrJwt\Parser\Cookie + * @uses PsrJwt\Parser\Query + */ + public function testGetTokenNoToken() + { + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getHeader') + ->with('authorization') + ->once() + ->andReturn([]); + $request->shouldReceive('getServerParams') + ->once() + ->andReturn([]); + $request->shouldReceive('getCookieParams') + ->once() + ->andReturn([]); + $request->shouldReceive('getQueryParams') + ->once() + ->andReturn([]); + $request->shouldReceive('getParsedBody') + ->twice() + ->andReturn([]); + + $auth = new Authenticate('jwt', 'secret'); + + $method = new ReflectionMethod(Authenticate::class, 'getToken'); + $method->setAccessible(true); + $result = $method->invokeArgs($auth, [$request]); + } + public function tearDown() { m::close(); From 1a0c36eac9b1cbb03550439c27004e58ffa193f3 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Sun, 28 Apr 2019 11:28:26 +0100 Subject: [PATCH 14/22] Deleted JwtAuthHandler and associated tests as it is no longer needed. --- src/JwtAuthHandler.php | 96 --------- tests/JwtAuthHandlerTest.php | 371 ----------------------------------- 2 files changed, 467 deletions(-) delete mode 100644 src/JwtAuthHandler.php delete mode 100644 tests/JwtAuthHandlerTest.php diff --git a/src/JwtAuthHandler.php b/src/JwtAuthHandler.php deleted file mode 100644 index 61aa9b5..0000000 --- a/src/JwtAuthHandler.php +++ /dev/null @@ -1,96 +0,0 @@ -tokenKey = $tokenKey; - - $this->secret = $secret; - } - - public function getSecret(): string - { - return $this->secret; - } - - private function validate(string $token): ResponseInterface - { - $parse = Jwt::parser($token, $this->getSecret()); - - $validate = new Validate($parse); - - $validationState = $validate->validate(); - - $validationState = $validate->validateNotBefore($validationState); - - return $this->validationResponse( - $validationState['code'], - $validationState['message'] - ); - } - - private function validationResponse(int $code, string $message): ResponseInterface - { - $factory = new Psr17Factory(); - - if (in_array($code, [1, 2, 3, 4, 5], true)) { - return $factory->createResponse(401, 'Unauthorized: ' . $message); - } - - return $factory->createResponse(200, 'Ok'); - } - - private function hasJwt(string $token): bool - { - return !empty($token); - } - - private function getToken(ServerRequestInterface $request): string - { - $parse = new Parse(['token_key' => $this->tokenKey]); - $parse->addParser(\PsrJwt\Parser\Bearer::class); - $parse->addParser(\PsrJwt\Parser\Cookie::class); - $parse->addParser(\PsrJwt\Parser\Body::class); - $parse->addParser(\PsrJwt\Parser\Query::class); - $parse->addParser(\PsrJwt\Parser\Server::class); - - $token = $parse->findToken($request); - - if ($this->hasJwt($token)) { - return $token; - } - - throw new ValidateException('JSON Web Token not set.', 11); - } - - public function handle(ServerRequestInterface $request): ResponseInterface - { - try { - $token = $this->getToken($request); - } catch (ValidateException $e) { - $factory = new Psr17Factory(); - return $factory->createResponse(400, 'Bad Request: ' . $e->getMessage()); - } - - return $this->validate($token); - } -} diff --git a/tests/JwtAuthHandlerTest.php b/tests/JwtAuthHandlerTest.php deleted file mode 100644 index 0576fa9..0000000 --- a/tests/JwtAuthHandlerTest.php +++ /dev/null @@ -1,371 +0,0 @@ -assertInstanceOf(JwtAuthHandler::class, $handler); - $this->assertInstanceOf(RequestHandlerInterface::class, $handler); - } - - /** - * @covers PsrJwt\JwtAuthHandler::handle - * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Validation\Validate - * @uses PsrJwt\Parser\Parse - * @uses PsrJwt\Parser\Body - * @uses PsrJwt\Parser\Bearer - * @uses PsrJwt\Parser\Server - * @uses PsrJwt\Parser\Query - * @uses PsrJwt\Parser\Cookie - */ - public function testJwtAuthHandlerResponse() - { - $jwt = Jwt::builder(); - $token = $jwt->setSecret('Secret123!456$') - ->setIssuer('localhost') - ->build() - ->getToken(); - - $request = m::mock(ServerRequestInterface::class); - $request->shouldReceive('getServerParams') - ->once() - ->andReturn(['jwt' => $token]); - $request->shouldReceive('getCookieParams') - ->once() - ->andReturn(['foo' => 'bar']); - $request->shouldReceive('getQueryParams') - ->once() - ->andReturn(['hello' => 'world']); - $request->shouldReceive('getParsedBody') - ->twice() - ->andReturn([]); - $request->shouldReceive('getHeader') - ->with('authorization') - ->once() - ->andReturn([]); - - $handler = new JwtAuthHandler('jwt', 'Secret123!456$'); - - $result = $handler->handle($request); - - $this->assertInstanceOf(ResponseInterface::class, $result); - $this->assertSame(200, $result->getStatusCode()); - $this->assertSame('Ok', $result->getReasonPhrase()); - } - - /** - * @covers PsrJwt\JwtAuthHandler::handle - * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Validation\Validate - * @uses PsrJwt\Parser\Parse - * @uses PsrJwt\Parser\Body - * @uses PsrJwt\Parser\Bearer - * @uses PsrJwt\Parser\Server - * @uses PsrJwt\Parser\Query - * @uses PsrJwt\Parser\Cookie - */ - public function testJwtAuthHandlerResponseBadRequest() - { - $jwt = Jwt::builder(); - - $request = m::mock(ServerRequestInterface::class); - $request->shouldReceive('getServerParams') - ->once() - ->andReturn([]); - $request->shouldReceive('getCookieParams') - ->once() - ->andReturn(['foo' => 'bar']); - $request->shouldReceive('getQueryParams') - ->once() - ->andReturn(['hello' => 'world']); - $request->shouldReceive('getParsedBody') - ->twice() - ->andReturn([]); - $request->shouldReceive('getHeader') - ->with('authorization') - ->once() - ->andReturn([]); - - $handler = new JwtAuthHandler('jwt', 'Secret123!456$'); - - $result = $handler->handle($request); - - $this->assertSame(400, $result->getStatusCode()); - $this->assertSame('Bad Request: JSON Web Token not set.', $result->getReasonPhrase()); - } - - /** - * @covers PsrJwt\JwtAuthHandler::hasJwt - * @uses PsrJwt\JwtAuthHandler::__construct - */ - public function testJwtAuthHandlerHasJwt() - { - $handler = new JwtAuthHandler('jwt', 'secret'); - - $method = new ReflectionMethod(JwtAuthHandler::class, 'hasJwt'); - $method->setAccessible(true); - $result = $method->invokeArgs($handler, ['abc.abc.abc']); - - $this->assertTrue($result); - } - - /** - * @covers PsrJwt\JwtAuthHandler::hasJwt - * @uses PsrJwt\JwtAuthHandler::__construct - */ - public function testJwtAuthHandlerHasJwtEmpty() - { - $handler = new JwtAuthHandler('jwt', 'secret'); - - $method = new ReflectionMethod(JwtAuthHandler::class, 'hasJwt'); - $method->setAccessible(true); - $result = $method->invokeArgs($handler, ['']); - - $this->assertFalse($result); - } - - /** - * @covers PsrJwt\JwtAuthHandler::getSecret - * @uses PsrJwt\JwtAuthHandler::__construct - */ - public function testGetSecret() - { - $handler = new JwtAuthHandler('jwt', 'secret'); - - $method = new ReflectionMethod(JwtAuthHandler::class, 'getSecret'); - $method->setAccessible(true); - $result = $method->invoke($handler); - - $this->assertSame('secret', $result); - } - - /** - * @covers PsrJwt\JwtAuthHandler::validate - * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Validation\Validate - */ - public function testValidate() - { - $jwt = Jwt::builder(); - $token = $jwt->setSecret('Secret123!456$') - ->setIssuer('localhost') - ->build() - ->getToken(); - - $handler = new JwtAuthHandler('jwt', 'Secret123!456$'); - - $method = new ReflectionMethod(JwtAuthHandler::class, 'validate'); - $method->setAccessible(true); - $result = $method->invokeArgs($handler, [$token]); - - $this->assertSame(200, $result->getStatusCode()); - $this->assertSame('Ok', $result->getReasonPhrase()); - } - - /** - * @covers PsrJwt\JwtAuthHandler::validate - * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Validation\Validate - */ - public function testValidateBadSecret() - { - $jwt = Jwt::builder(); - $token = $jwt->setSecret('Secret123!456$') - ->setIssuer('localhost') - ->build() - ->getToken(); - - $handler = new JwtAuthHandler('jwt', 'Secret'); - - $method = new ReflectionMethod(JwtAuthHandler::class, 'validate'); - $method->setAccessible(true); - $result = $method->invokeArgs($handler, [$token]); - - $this->assertSame(401, $result->getStatusCode()); - $this->assertSame('Unauthorized: Signature is invalid.', $result->getReasonPhrase()); - } - - /** - * @covers PsrJwt\JwtAuthHandler::validate - * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Validation\Validate - */ - public function testValidateBadExpiration() - { - $jwt = Jwt::builder(); - $token = $jwt->setSecret('Secret123!456$') - ->setIssuer('localhost') - ->setPayloadClaim('exp', time() - 10) - ->build() - ->getToken(); - - $handler = new JwtAuthHandler('jwt', 'Secret123!456$'); - - $method = new ReflectionMethod(JwtAuthHandler::class, 'validate'); - $method->setAccessible(true); - $result = $method->invokeArgs($handler, [$token]); - - $this->assertSame(401, $result->getStatusCode()); - $this->assertSame('Unauthorized: Expiration claim has expired.', $result->getReasonPhrase()); - } - - /** - * @covers PsrJwt\JwtAuthHandler::validate - * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Validation\Validate - */ - public function testValidateBadNotBefore() - { - $jwt = Jwt::builder(); - $token = $jwt->setSecret('Secret123!456$') - ->setIssuer('localhost') - ->setPayloadClaim('nbf', time() + 60) - ->build() - ->getToken(); - - $handler = new JwtAuthHandler('jwt', 'Secret123!456$'); - - $method = new ReflectionMethod(JwtAuthHandler::class, 'validate'); - $method->setAccessible(true); - $result = $method->invokeArgs($handler, [$token]); - - $this->assertSame(401, $result->getStatusCode()); - $this->assertSame('Unauthorized: Not Before claim has not elapsed.', $result->getReasonPhrase()); - } - - /** - * @covers PsrJwt\JwtAuthHandler::validationResponse - * @uses PsrJwt\JwtAuthHandler::__construct - */ - public function testValidationResponse() - { - $handler = new JwtAuthHandler('jwt', 'secret'); - - $method = new ReflectionMethod(JwtAuthHandler::class, 'validationResponse'); - $method->setAccessible(true); - $result = $method->invokeArgs($handler, [0, 'Ok']); - - $this->assertInstanceOf(ResponseInterface::class, $result); - $this->assertSame(200, $result->getStatusCode()); - $this->assertSame('Ok', $result->getReasonPhrase()); - } - - /** - * @covers PsrJwt\JwtAuthHandler::validationResponse - * @uses PsrJwt\JwtAuthHandler::__construct - */ - public function testValidationResponseErrors() - { - $handler = new JwtAuthHandler('jwt', 'secret'); - - $method = new ReflectionMethod(JwtAuthHandler::class, 'validationResponse'); - $method->setAccessible(true); - - $errors = [ - [1, 'Error 1'], - [2, 'Error 1'], - [3, 'Error 1'], - [4, 'Error 1'], - [5, 'Error 1'] - ]; - - foreach ($errors as $error) { - $result = $method->invokeArgs($handler, [$error[0], $error[1]]); - - $this->assertInstanceOf(ResponseInterface::class, $result); - $this->assertSame(401, $result->getStatusCode()); - $this->assertSame('Unauthorized: ' . $error[1], $result->getReasonPhrase()); - } - } - - /** - * @covers PsrJwt\JwtAuthHandler::getToken - * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\Parser\Parse - * @uses PsrJwt\Parser\Bearer - */ - public function testGetToken() - { - $request = m::mock(ServerRequestInterface::class); - $request->shouldReceive('getHeader') - ->with('authorization') - ->once() - ->andReturn(['Bearer abc.def.ghi']); - - $handler = new JwtAuthHandler('jwt', 'secret'); - - $method = new ReflectionMethod(JwtAuthHandler::class, 'getToken'); - $method->setAccessible(true); - $result = $method->invokeArgs($handler, [$request]); - - $this->assertSame('abc.def.ghi', $result); - } - - /** - * @expectedException ReallySimpleJWT\Exception\ValidateException - * @expectedExceptionMessage JSON Web Token not set. - * @expectedExceptionCode 11 - * @covers PsrJwt\JwtAuthHandler::getToken - * @uses PsrJwt\JwtAuthHandler - * @uses PsrJwt\Parser\Parse - * @uses PsrJwt\Parser\Bearer - * @uses PsrJwt\Parser\Server - * @uses PsrJwt\Parser\Body - * @uses PsrJwt\Parser\Cookie - * @uses PsrJwt\Parser\Query - */ - public function testGetTokenNoToken() - { - $request = m::mock(ServerRequestInterface::class); - $request->shouldReceive('getHeader') - ->with('authorization') - ->once() - ->andReturn([]); - $request->shouldReceive('getServerParams') - ->once() - ->andReturn([]); - $request->shouldReceive('getCookieParams') - ->once() - ->andReturn([]); - $request->shouldReceive('getQueryParams') - ->once() - ->andReturn([]); - $request->shouldReceive('getParsedBody') - ->twice() - ->andReturn([]); - - $handler = new JwtAuthHandler('jwt', 'secret'); - - $method = new ReflectionMethod(JwtAuthHandler::class, 'getToken'); - $method->setAccessible(true); - $result = $method->invokeArgs($handler, [$request]); - } - - public function tearDown() { - m::close(); - } -} From 795e932659e458dfba76e9aecbf098e9c8be47ca Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Sun, 28 Apr 2019 18:16:04 +0100 Subject: [PATCH 15/22] Fixed library and tests so they work with new Auth namespace and classes. --- src/Factory/JwtAuth.php | 17 +++++++---------- src/JwtAuthInvokable.php | 18 ++++++++++-------- src/JwtAuthMiddleware.php | 18 +++++++++++++++++- tests/Factory/JwtAuthTest.php | 16 ++-------------- tests/JwtAuthInvokableTest.php | 14 +++++++------- tests/JwtAuthMiddlewareTest.php | 21 +++++++++++++++++---- 6 files changed, 60 insertions(+), 44 deletions(-) diff --git a/src/Factory/JwtAuth.php b/src/Factory/JwtAuth.php index 1e065c7..3c24c4d 100644 --- a/src/Factory/JwtAuth.php +++ b/src/Factory/JwtAuth.php @@ -5,25 +5,22 @@ namespace PsrJwt\Factory; use PsrJwt\JwtAuthMiddleware; -use PsrJwt\JwtAuthHandler; +use PsrJwt\Auth\Authenticate; use PsrJwt\JwtAuthInvokable; class JwtAuth { - public static function middleware(): JwtAuthMiddleware + public static function middleware(string $tokenKey, string $secret): JwtAuthMiddleware { - return new JwtAuthMiddleware(); - } + $auth = new Authenticate($tokenKey, $secret); - public static function handler($tokenKey, $secret): JwtAuthHandler - { - return new JwtAuthHandler($tokenKey, $secret); + return new JwtAuthMiddleware($auth); } - public static function invokable($tokenKey, $secret): JwtAuthInvokable + public static function invokable(string $tokenKey, string $secret): JwtAuthInvokable { - $handler = new JwtAuthHandler($tokenKey, $secret); + $auth = new Authenticate($tokenKey, $secret); - return new JwtAuthInvokable($handler); + return new JwtAuthInvokable($auth); } } diff --git a/src/JwtAuthInvokable.php b/src/JwtAuthInvokable.php index 236e3a7..c4abf80 100644 --- a/src/JwtAuthInvokable.php +++ b/src/JwtAuthInvokable.php @@ -4,17 +4,18 @@ namespace PsrJwt; +use Nyholm\Psr7\Factory\Psr17Factory; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; -use PsrJwt\JwtAuthHandler; +use PsrJwt\Auth\Authenticate; class JwtAuthInvokable { - private $handler; + private $authenticate; - public function __construct(JwtAuthHandler $handler) + public function __construct(Authenticate $authenticate) { - $this->handler = $handler; + $this->authenticate = $authenticate; } public function __invoke( @@ -22,12 +23,13 @@ public function __invoke( ResponseInterface $response, callable $next ): ResponseInterface { - $response = $this->handler->handle($request); + $auth = $this->authenticate->authenticate($request); - if ($response->getStatusCode() !== 200) { - return $response; + if ($auth->getCode() === 200) { + return $next($request, $response); } - return $next($request, $response); + $factory = new Psr17Factory(); + return $factory->createResponse($auth->getCode(), $auth->getMessage()); } } diff --git a/src/JwtAuthMiddleware.php b/src/JwtAuthMiddleware.php index ae385f4..4e98d38 100644 --- a/src/JwtAuthMiddleware.php +++ b/src/JwtAuthMiddleware.php @@ -4,15 +4,31 @@ namespace PsrJwt; +use Nyholm\Psr7\Factory\Psr17Factory; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; +use PsrJwt\Auth\Authenticate; class JwtAuthMiddleware implements MiddlewareInterface { + private $authenticate; + + public function __construct(Authenticate $authenticate) + { + $this->authenticate = $authenticate; + } + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { - return $handler->handle($request); + $auth = $this->authenticate->authenticate($request); + + if ($auth->getCode() === 200) { + return $handler->handle($request); + } + + $factory = new Psr17Factory(); + return $factory->createResponse($auth->getCode(), $auth->getMessage()); } } diff --git a/tests/Factory/JwtAuthTest.php b/tests/Factory/JwtAuthTest.php index 2569bfa..dd307e8 100644 --- a/tests/Factory/JwtAuthTest.php +++ b/tests/Factory/JwtAuthTest.php @@ -5,7 +5,7 @@ use PHPUnit\Framework\TestCase; use PsrJwt\Factory\JwtAuth; use PsrJwt\JwtAuthMiddleware; -use PsrJwt\JwtAuthHandler; +use PsrJwt\Auth\Authenticate; use PsrJwt\JwtAuthInvokable; class JwtAuthTest extends TestCase @@ -17,7 +17,7 @@ public function testJwtAuthMiddleware() { $this->assertInstanceOf( JwtAuthMiddleware::class, - JwtAuth::middleware() + JwtAuth::middleware('jwt', '$Secret123!') ); } @@ -33,16 +33,4 @@ public function testJwtAuthInvokable() JwtAuth::invokable('jwt', '$Secret123!') ); } - - /** - * @covers PsrJwt\Factory\JwtAuth::handler - * @uses PsrJwt\JwtAuthHandler::__construct - */ - public function testJwtAuthHandler() - { - $this->assertInstanceOf( - JwtAuthHandler::class, - JwtAuth::handler('jwt', '$Secret123!') - ); - } } diff --git a/tests/JwtAuthInvokableTest.php b/tests/JwtAuthInvokableTest.php index 57bf962..26d720a 100644 --- a/tests/JwtAuthInvokableTest.php +++ b/tests/JwtAuthInvokableTest.php @@ -5,7 +5,7 @@ use PHPUnit\Framework\TestCase; use PsrJwt\JwtAuthInvokable; use PsrJwt\Factory\Jwt; -use PsrJwt\JwtAuthHandler; +use PsrJwt\Auth\Authenticate; use PsrJwt\JwtAuthException; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -21,9 +21,9 @@ class JwtAuthInvokableTest extends TestCase */ public function testJwtAuthInokable() { - $handler = new JwtAuthHandler('jwt', 'secret'); + $auth = new Authenticate('jwt', 'secret'); - $invokable = new JwtAuthInvokable($handler); + $invokable = new JwtAuthInvokable($auth); $this->assertInstanceOf(JwtAuthInvokable::class, $invokable); } @@ -58,9 +58,9 @@ public function testInvoke() return $response; }; - $handler = new JwtAuthHandler('jwt', 'Secret123!456$'); + $auth = new Authenticate('jwt', 'Secret123!456$'); - $invokable = new JwtAuthInvokable($handler); + $invokable = new JwtAuthInvokable($auth); $result = $invokable($request, $response, $next); @@ -106,9 +106,9 @@ public function testInvokeFail() return $response; }; - $handler = new JwtAuthHandler('jwt', 'secret'); + $auth = new Authenticate('jwt', 'secret'); - $invokable = new JwtAuthInvokable($handler); + $invokable = new JwtAuthInvokable($auth); $result = $invokable($request, $response, $next); diff --git a/tests/JwtAuthMiddlewareTest.php b/tests/JwtAuthMiddlewareTest.php index a74c74b..b997ec1 100644 --- a/tests/JwtAuthMiddlewareTest.php +++ b/tests/JwtAuthMiddlewareTest.php @@ -3,9 +3,10 @@ namespace Tests; use PHPUnit\Framework\TestCase; +use Nyholm\Psr7\Factory\Psr17Factory; use PsrJwt\Factory\Jwt; use PsrJwt\JwtAuthMiddleware; -use PsrJwt\JwtAuthHandler; +use PsrJwt\Auth\Authenticate; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; @@ -19,7 +20,9 @@ class JwtAuthMiddlewareTest extends TestCase */ public function testJwtAuthProcess() { - $process = new JwtAuthMiddleware(); + $authenticate = new Authenticate('jwt', 'secret'); + + $process = new JwtAuthMiddleware($authenticate); $this->assertInstanceOf(JwtAuthMiddleware::class, $process); $this->assertInstanceOf(MiddlewareInterface::class, $process); @@ -48,13 +51,23 @@ public function testProcess() ->once() ->andReturn(['Bearer ' . $token]); - $handler = new JwtAuthHandler('jwt', 'Secret123!456$'); + $response = new Psr17Factory(); + $response = $response->createResponse(200, 'Ok'); + + $handler = m::mock(RequestHandlerInterface::class); + $handler->shouldReceive('handle') + ->once() + ->andReturn($response); + + $authenticate = new Authenticate('jwt', 'Secret123!456$'); - $process = new JwtAuthMiddleware(); + $process = new JwtAuthMiddleware($authenticate); $result = $process->process($request, $handler); $this->assertInstanceOf(ResponseInterface::class, $result); + $this->assertSame(200, $result->getStatusCode()); + $this->assertSame('Ok', $result->getReasonPhrase()); } public function tearDown() { From ff913d70977f7ac9597d88a045173e7114e742ae Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Sun, 28 Apr 2019 18:30:03 +0100 Subject: [PATCH 16/22] Fixed tests so covers and annotations are correct and tests pass. --- tests/Auth/AuthTest.php | 5 +++++ tests/Auth/AuthenticateTest.php | 15 +++++++++++++-- tests/Factory/JwtAuthTest.php | 4 +++- tests/JwtAuthInvokableTest.php | 9 ++++++--- tests/JwtAuthMiddlewareTest.php | 5 ++++- 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/tests/Auth/AuthTest.php b/tests/Auth/AuthTest.php index 86716f8..e6fa1c3 100644 --- a/tests/Auth/AuthTest.php +++ b/tests/Auth/AuthTest.php @@ -7,6 +7,9 @@ class AuthTest extends TestCase { + /** + * @covers PsrJwt\Auth\Auth::__construct + */ public function testAuth() { $auth = new Auth(200, 'Ok'); @@ -16,6 +19,7 @@ public function testAuth() /** * @depends testAuth + * @covers PsrJwt\Auth\Auth::getCode */ public function testGetCode($auth) { @@ -24,6 +28,7 @@ public function testGetCode($auth) /** * @depends testAuth + * @covers PsrJwt\Auth\Auth::getMessage */ public function testGetMessage($auth) { diff --git a/tests/Auth/AuthenticateTest.php b/tests/Auth/AuthenticateTest.php index 48eb4a6..1d10310 100644 --- a/tests/Auth/AuthenticateTest.php +++ b/tests/Auth/AuthenticateTest.php @@ -12,6 +12,9 @@ class AuthenticateTest extends TestCase { + /** + * @covers PsrJwt\Auth\Authenticate::__construct + */ public function testAuthenticate() { $auth = new Authenticate('jwt', 'secret'); @@ -19,8 +22,9 @@ public function testAuthenticate() } /** - * @covers PsrJwt\Auth\Authenticate::handle + * @covers PsrJwt\Auth\Authenticate::authenticate * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Auth\Auth * @uses PsrJwt\Factory\Jwt * @uses PsrJwt\Validation\Validate * @uses PsrJwt\Parser\Parse @@ -66,8 +70,9 @@ public function testAuthenticateOk() } /** - * @covers PsrJwt\Auth\Authenticate::handle + * @covers PsrJwt\Auth\Authenticate::authenticate * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Auth\Auth * @uses PsrJwt\Factory\Jwt * @uses PsrJwt\Validation\Validate * @uses PsrJwt\Parser\Parse @@ -155,6 +160,7 @@ public function testGetSecret() /** * @covers PsrJwt\Auth\Authenticate::validate * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Auth\Auth * @uses PsrJwt\Factory\Jwt * @uses PsrJwt\Validation\Validate */ @@ -179,6 +185,7 @@ public function testValidate() /** * @covers PsrJwt\Auth\Authenticate::validate * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Auth\Auth * @uses PsrJwt\Factory\Jwt * @uses PsrJwt\Validation\Validate */ @@ -203,6 +210,7 @@ public function testValidateBadSecret() /** * @covers PsrJwt\Auth\Authenticate::validate * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Auth\Auth * @uses PsrJwt\Factory\Jwt * @uses PsrJwt\Validation\Validate */ @@ -228,6 +236,7 @@ public function testValidateBadExpiration() /** * @covers PsrJwt\Auth\Authenticate::validate * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Auth\Auth * @uses PsrJwt\Factory\Jwt * @uses PsrJwt\Validation\Validate */ @@ -253,6 +262,7 @@ public function testValidateBadNotBefore() /** * @covers PsrJwt\Auth\Authenticate::validationResponse * @uses PsrJwt\Auth\Authenticate::__construct + * @uses PsrJwt\Auth\Auth */ public function testValidationResponse() { @@ -270,6 +280,7 @@ public function testValidationResponse() /** * @covers PsrJwt\Auth\Authenticate::validationResponse * @uses PsrJwt\Auth\Authenticate::__construct + * @uses PsrJwt\Auth\Auth */ public function testValidationResponseErrors() { diff --git a/tests/Factory/JwtAuthTest.php b/tests/Factory/JwtAuthTest.php index dd307e8..1a63bd7 100644 --- a/tests/Factory/JwtAuthTest.php +++ b/tests/Factory/JwtAuthTest.php @@ -12,6 +12,8 @@ class JwtAuthTest extends TestCase { /** * @covers PsrJwt\Factory\JwtAuth::middleware + * @uses PsrJwt\JwtAuthMiddleware::__construct + * @uses PsrJwt\Auth\Authenticate */ public function testJwtAuthMiddleware() { @@ -23,8 +25,8 @@ public function testJwtAuthMiddleware() /** * @covers PsrJwt\Factory\JwtAuth::invokable - * @uses PsrJwt\JwtAuthHandler::__construct * @uses PsrJwt\JwtAuthInvokable::__construct + * @uses PsrJwt\Auth\Authenticate */ public function testJwtAuthInvokable() { diff --git a/tests/JwtAuthInvokableTest.php b/tests/JwtAuthInvokableTest.php index 26d720a..4d104fe 100644 --- a/tests/JwtAuthInvokableTest.php +++ b/tests/JwtAuthInvokableTest.php @@ -17,7 +17,8 @@ class JwtAuthInvokableTest extends TestCase { /** * @covers PsrJwt\JwtAuthInvokable::__construct - * @uses PsrJwt\JwtAuthHandler::__construct + * @uses PsrJwt\Auth\Authenticate::__construct + * @uses PsrJwt\Auth\Auth */ public function testJwtAuthInokable() { @@ -31,7 +32,8 @@ public function testJwtAuthInokable() /** * @covers PsrJwt\JwtAuthInvokable::__invoke * @uses PsrJwt\JwtAuthInvokable::__construct - * @uses PsrJwt\JwtAuthHandler + * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Auth\Auth * @uses PsrJwt\Factory\Jwt * @uses PsrJwt\Validation\Validate * @uses PsrJwt\Parser\Parse @@ -70,7 +72,8 @@ public function testInvoke() /** * @covers PsrJwt\JwtAuthInvokable::__invoke * @uses PsrJwt\JwtAuthInvokable - * @uses PsrJwt\JwtAuthHandler + * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Auth\Auth * @uses PsrJwt\Factory\Jwt * @uses PsrJwt\Validation\Validate * @uses PsrJwt\Parser\Parse diff --git a/tests/JwtAuthMiddlewareTest.php b/tests/JwtAuthMiddlewareTest.php index b997ec1..b8a36af 100644 --- a/tests/JwtAuthMiddlewareTest.php +++ b/tests/JwtAuthMiddlewareTest.php @@ -17,6 +17,7 @@ class JwtAuthMiddlewareTest extends TestCase { /** * @covers PsrJwt\JwtAuthMiddleware + * @uses PsrJwt\Auth\Authenticate */ public function testJwtAuthProcess() { @@ -30,8 +31,10 @@ public function testJwtAuthProcess() /** * @covers PsrJwt\JwtAuthMiddleware::process + * @uses PsrJwt\JwtAuthMiddleware::__construct + * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Auth\Auth * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\JwtAuthHandler * @uses PsrJwt\Parser\Parse * @uses PsrJwt\Validation\Validate * @uses PsrJwt\Parser\Bearer From 9d1febada7d31179594f2edfee131d3405620d84 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Tue, 30 Apr 2019 11:16:40 +0100 Subject: [PATCH 17/22] Removed pointless duplication between JwtAuthInvokable class and JwtAuthMiddleware class. --- src/Factory/JwtAuth.php | 7 -- src/JwtAuthInvokable.php | 35 --------- src/JwtAuthMiddleware.php | 20 +++++ tests/Factory/JwtAuthTest.php | 13 ---- tests/JwtAuthInvokableTest.php | 125 -------------------------------- tests/JwtAuthMiddlewareTest.php | 90 +++++++++++++++++++++++ 6 files changed, 110 insertions(+), 180 deletions(-) delete mode 100644 src/JwtAuthInvokable.php delete mode 100644 tests/JwtAuthInvokableTest.php diff --git a/src/Factory/JwtAuth.php b/src/Factory/JwtAuth.php index 3c24c4d..581dcf6 100644 --- a/src/Factory/JwtAuth.php +++ b/src/Factory/JwtAuth.php @@ -16,11 +16,4 @@ public static function middleware(string $tokenKey, string $secret): JwtAuthMidd return new JwtAuthMiddleware($auth); } - - public static function invokable(string $tokenKey, string $secret): JwtAuthInvokable - { - $auth = new Authenticate($tokenKey, $secret); - - return new JwtAuthInvokable($auth); - } } diff --git a/src/JwtAuthInvokable.php b/src/JwtAuthInvokable.php deleted file mode 100644 index c4abf80..0000000 --- a/src/JwtAuthInvokable.php +++ /dev/null @@ -1,35 +0,0 @@ -authenticate = $authenticate; - } - - public function __invoke( - ServerRequestInterface $request, - ResponseInterface $response, - callable $next - ): ResponseInterface { - $auth = $this->authenticate->authenticate($request); - - if ($auth->getCode() === 200) { - return $next($request, $response); - } - - $factory = new Psr17Factory(); - return $factory->createResponse($auth->getCode(), $auth->getMessage()); - } -} diff --git a/src/JwtAuthMiddleware.php b/src/JwtAuthMiddleware.php index 4e98d38..dbac2ae 100644 --- a/src/JwtAuthMiddleware.php +++ b/src/JwtAuthMiddleware.php @@ -10,6 +10,7 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; use PsrJwt\Auth\Authenticate; +use PsrJwt\Auth\Auth; class JwtAuthMiddleware implements MiddlewareInterface { @@ -20,6 +21,20 @@ public function __construct(Authenticate $authenticate) $this->authenticate = $authenticate; } + public function __invoke( + ServerRequestInterface $request, + ResponseInterface $response, + callable $next + ): ResponseInterface { + $auth = $this->authenticate->authenticate($request); + + if ($auth->getCode() === 200) { + return $next($request, $response); + } + + return $this->failResponse($auth); + } + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { $auth = $this->authenticate->authenticate($request); @@ -28,6 +43,11 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface return $handler->handle($request); } + return $this->failResponse($auth); + } + + private function failResponse(Auth $auth): ResponseInterface + { $factory = new Psr17Factory(); return $factory->createResponse($auth->getCode(), $auth->getMessage()); } diff --git a/tests/Factory/JwtAuthTest.php b/tests/Factory/JwtAuthTest.php index 1a63bd7..1f0f971 100644 --- a/tests/Factory/JwtAuthTest.php +++ b/tests/Factory/JwtAuthTest.php @@ -22,17 +22,4 @@ public function testJwtAuthMiddleware() JwtAuth::middleware('jwt', '$Secret123!') ); } - - /** - * @covers PsrJwt\Factory\JwtAuth::invokable - * @uses PsrJwt\JwtAuthInvokable::__construct - * @uses PsrJwt\Auth\Authenticate - */ - public function testJwtAuthInvokable() - { - $this->assertInstanceOf( - JwtAuthInvokable::class, - JwtAuth::invokable('jwt', '$Secret123!') - ); - } } diff --git a/tests/JwtAuthInvokableTest.php b/tests/JwtAuthInvokableTest.php deleted file mode 100644 index 4d104fe..0000000 --- a/tests/JwtAuthInvokableTest.php +++ /dev/null @@ -1,125 +0,0 @@ -assertInstanceOf(JwtAuthInvokable::class, $invokable); - } - - /** - * @covers PsrJwt\JwtAuthInvokable::__invoke - * @uses PsrJwt\JwtAuthInvokable::__construct - * @uses PsrJwt\Auth\Authenticate - * @uses PsrJwt\Auth\Auth - * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Validation\Validate - * @uses PsrJwt\Parser\Parse - * @uses PsrJwt\Parser\Bearer - */ - public function testInvoke() - { - $jwt = Jwt::builder(); - $token = $jwt->setSecret('Secret123!456$') - ->setIssuer('localhost') - ->setPayloadClaim('nbf', time() - 60) - ->build() - ->getToken(); - - $request = m::mock(ServerRequestInterface::class); - $request->shouldReceive('getHeader') - ->with('authorization') - ->once() - ->andReturn(['Bearer ' . $token]); - - $response = m::mock(ResponseInterface::class); - - $next = function($request, $response) { - return $response; - }; - - $auth = new Authenticate('jwt', 'Secret123!456$'); - - $invokable = new JwtAuthInvokable($auth); - - $result = $invokable($request, $response, $next); - - $this->assertInstanceOf(ResponseInterface::class, $result); - } - - /** - * @covers PsrJwt\JwtAuthInvokable::__invoke - * @uses PsrJwt\JwtAuthInvokable - * @uses PsrJwt\Auth\Authenticate - * @uses PsrJwt\Auth\Auth - * @uses PsrJwt\Factory\Jwt - * @uses PsrJwt\Validation\Validate - * @uses PsrJwt\Parser\Parse - * @uses PsrJwt\Parser\Body - * @uses PsrJwt\Parser\Bearer - * @uses PsrJwt\Parser\Server - * @uses PsrJwt\Parser\Query - * @uses PsrJwt\Parser\Cookie - */ - public function testInvokeFail() - { - $request = m::mock(ServerRequestInterface::class); - $request->shouldReceive('getServerParams') - ->once() - ->andReturn(['jwt' => 'abc.abc.abc']); - $request->shouldReceive('getCookieParams') - ->once() - ->andReturn(['hello' => 'world']); - $request->shouldReceive('getQueryParams') - ->once() - ->andReturn(['car' => 'park']); - $request->shouldReceive('getParsedBody') - ->twice() - ->andReturn(['gary' => 'barlow']); - $request->shouldReceive('getHeader') - ->with('authorization') - ->once() - ->andReturn([]); - - $response = m::mock(ResponseInterface::class); - - $next = function($request, $response) { - return $response; - }; - - $auth = new Authenticate('jwt', 'secret'); - - $invokable = new JwtAuthInvokable($auth); - - $result = $invokable($request, $response, $next); - - $this->assertSame(401, $result->getStatusCode()); - $this->assertSame('Unauthorized: Signature is invalid.', $result->getReasonPhrase()); - } - - public function tearDown() { - m::close(); - } -} diff --git a/tests/JwtAuthMiddlewareTest.php b/tests/JwtAuthMiddlewareTest.php index b8a36af..55fbc3b 100644 --- a/tests/JwtAuthMiddlewareTest.php +++ b/tests/JwtAuthMiddlewareTest.php @@ -73,6 +73,96 @@ public function testProcess() $this->assertSame('Ok', $result->getReasonPhrase()); } + /** + * @covers PsrJwt\JwtAuthMiddleware::__invoke + * @uses PsrJwt\JwtAuthMiddleware::__construct + * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Auth\Auth + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Validation\Validate + * @uses PsrJwt\Parser\Parse + * @uses PsrJwt\Parser\Bearer + */ + public function testInvoke() + { + $jwt = Jwt::builder(); + $token = $jwt->setSecret('Secret123!456$') + ->setIssuer('localhost') + ->setPayloadClaim('nbf', time() - 60) + ->build() + ->getToken(); + + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getHeader') + ->with('authorization') + ->once() + ->andReturn(['Bearer ' . $token]); + + $response = m::mock(ResponseInterface::class); + + $next = function($request, $response) { + return $response; + }; + + $auth = new Authenticate('jwt', 'Secret123!456$'); + + $invokable = new JwtAuthMiddleware($auth); + + $result = $invokable($request, $response, $next); + + $this->assertInstanceOf(ResponseInterface::class, $result); + } + + /** + * @covers PsrJwt\JwtAuthMiddleware::__invoke + * @uses PsrJwt\JwtAuthMiddleware + * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Auth\Auth + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Validation\Validate + * @uses PsrJwt\Parser\Parse + * @uses PsrJwt\Parser\Body + * @uses PsrJwt\Parser\Bearer + * @uses PsrJwt\Parser\Server + * @uses PsrJwt\Parser\Query + * @uses PsrJwt\Parser\Cookie + */ + public function testInvokeFail() + { + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getServerParams') + ->once() + ->andReturn(['jwt' => 'abc.abc.abc']); + $request->shouldReceive('getCookieParams') + ->once() + ->andReturn(['hello' => 'world']); + $request->shouldReceive('getQueryParams') + ->once() + ->andReturn(['car' => 'park']); + $request->shouldReceive('getParsedBody') + ->twice() + ->andReturn(['gary' => 'barlow']); + $request->shouldReceive('getHeader') + ->with('authorization') + ->once() + ->andReturn([]); + + $response = m::mock(ResponseInterface::class); + + $next = function($request, $response) { + return $response; + }; + + $auth = new Authenticate('jwt', 'secret'); + + $invokable = new JwtAuthMiddleware($auth); + + $result = $invokable($request, $response, $next); + + $this->assertSame(401, $result->getStatusCode()); + $this->assertSame('Unauthorized: Signature is invalid.', $result->getReasonPhrase()); + } + public function tearDown() { m::close(); } From 9389ad35635615db41804731874a387ae41b0e12 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Tue, 30 Apr 2019 14:00:22 +0100 Subject: [PATCH 18/22] Added documentation to README to better explain how to use and implement the library. --- README.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index db64d72..2d82049 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,64 @@ # PSR-JWT [![Build Status](https://travis-ci.org/RobDWaller/psr-jwt.svg?branch=master)](https://travis-ci.org/RobDWaller/psr-jwt) [![codecov](https://codecov.io/gh/RobDWaller/psr-jwt/branch/master/graph/badge.svg)](https://codecov.io/gh/RobDWaller/psr-jwt) -A PSR-7 and PSR-15 compliant JSON Web Token Middleware Library. +A PSR-7 and PSR-15 compliant JSON Web Token Middleware Library. Currently in alpha and built on top of [ReallySimpleJWT](https://github.com/RobDWaller/ReallySimpleJWT). -Currently in alpha and built on top of [ReallySimpleJWT](https://github.com/RobDWaller/ReallySimpleJWT). +The library allows you to create JSON Web Tokens and then validate them using PSR-15 compliant middleware which can be added to compatible frameworks. -For more information on JSON Web Tokens please read [RFC 7519](https://tools.ietf.org/html/rfc7519). Also to learn more about how to pass JSON Web Tokens to web applications please read up on bearer token authorization in [RFC 6750](https://tools.ietf.org/html/rfc6750). +For more information on JSON Web Tokens please read [RFC 7519](https://tools.ietf.org/html/rfc7519). Also to learn more about how to pass JSON Web Tokens to web applications please read up on bearer token authorization in [RFC 6750](https://tools.ietf.org/html/rfc6750). + +## Setup + +Via Composer on the command line: + +```bash +composer require rbdwllr/psr-jwt +``` + +Via composer.json: + +```javascript +"require": { + "rbdwllr/psr-jwt": "^0.1" +} +``` + +## Usage + +PSR-JWT can be used with any PSR-7 / PSR-15 compliant framework. Just call the middleware factory method and it will return a middleware instance that exposes two methods, `__invoke()` and `process()`. The later will work with PSR-15 compliant frameworks like Zend Expressive and the former will work with older PSR-7 compliant frameworks like Slim PHP v3. + +```php +\PsrJwt\Factory\JwtAuth::middleware('tokenKey', 'secret'); +``` + +The `tokenKey` is the key required to retrieve the JSON Web Token from a cookie, query parameter or the request body. By default though the library looks for tokens in bearer field of the authorization header. + +The `secret` is the string required to hash the JSON Web Token signature. + +### Slim PHP 3.0 Example Implementation + +```php +// Can be added to any routes file in Slim, often index.php. +$app->get('/jwt', function (Request $request, Response $response) { + $response->getBody()->write("JSON Web Token is Valid!"); + + return $response; +})->add(\PsrJwt\Factory\JwtAuth::middleware('jwt', 'Secret123!456$')); +``` + +### Zend Expressive Example Implementation + +```php +// Add to the config/pipeline.php file. +$app->pipe('/api', \PsrJwt\Factory\JwtAuth::middleware('jwt', '!secReT$123*')); +``` + +### Generate JSON Web Token + +To generate JSON Web Tokens PsrJwt offers a wrapper for the library ReallySimpleJWT. You can create an instance of the ReallySimpleJWT builder by calling the built in factory method. + +```php +\PsrJwt\Factory\Jwt::builder(); +``` + +For more information on creating tokens please read the ReallySimpleJWT documentation. From 28b12d6aa8992580ccd31e859aad65c12df475f8 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Wed, 1 May 2019 21:56:36 +0100 Subject: [PATCH 19/22] Removed completely pointless Server parser class, not somewhere you should store a JWT. --- src/Auth/Authenticate.php | 1 - src/Parser/Server.php | 23 ----------------- tests/Auth/AuthenticateTest.php | 14 +--------- tests/JwtAuthMiddlewareTest.php | 8 ++---- tests/Parser/ServerTest.php | 45 --------------------------------- 5 files changed, 3 insertions(+), 88 deletions(-) delete mode 100644 src/Parser/Server.php delete mode 100644 tests/Parser/ServerTest.php diff --git a/src/Auth/Authenticate.php b/src/Auth/Authenticate.php index b8e8fe1..8d7b238 100644 --- a/src/Auth/Authenticate.php +++ b/src/Auth/Authenticate.php @@ -77,7 +77,6 @@ private function getToken(ServerRequestInterface $request): string $parse->addParser(\PsrJwt\Parser\Cookie::class); $parse->addParser(\PsrJwt\Parser\Body::class); $parse->addParser(\PsrJwt\Parser\Query::class); - $parse->addParser(\PsrJwt\Parser\Server::class); $token = $parse->findToken($request); diff --git a/src/Parser/Server.php b/src/Parser/Server.php deleted file mode 100644 index ab3163f..0000000 --- a/src/Parser/Server.php +++ /dev/null @@ -1,23 +0,0 @@ -arguments = $arguments; - } - - public function parse(ServerRequestInterface $request): string - { - return $request->getServerParams()[$this->arguments['token_key']] ?? ''; - } -} diff --git a/tests/Auth/AuthenticateTest.php b/tests/Auth/AuthenticateTest.php index 1d10310..eec8b76 100644 --- a/tests/Auth/AuthenticateTest.php +++ b/tests/Auth/AuthenticateTest.php @@ -30,7 +30,6 @@ public function testAuthenticate() * @uses PsrJwt\Parser\Parse * @uses PsrJwt\Parser\Body * @uses PsrJwt\Parser\Bearer - * @uses PsrJwt\Parser\Server * @uses PsrJwt\Parser\Query * @uses PsrJwt\Parser\Cookie */ @@ -43,15 +42,12 @@ public function testAuthenticateOk() ->getToken(); $request = m::mock(ServerRequestInterface::class); - $request->shouldReceive('getServerParams') - ->once() - ->andReturn(['jwt' => $token]); $request->shouldReceive('getCookieParams') ->once() ->andReturn(['foo' => 'bar']); $request->shouldReceive('getQueryParams') ->once() - ->andReturn(['hello' => 'world']); + ->andReturn(['jwt' => $token]); $request->shouldReceive('getParsedBody') ->twice() ->andReturn([]); @@ -78,7 +74,6 @@ public function testAuthenticateOk() * @uses PsrJwt\Parser\Parse * @uses PsrJwt\Parser\Body * @uses PsrJwt\Parser\Bearer - * @uses PsrJwt\Parser\Server * @uses PsrJwt\Parser\Query * @uses PsrJwt\Parser\Cookie */ @@ -87,9 +82,6 @@ public function testAuthenticateBadRequest() $jwt = Jwt::builder(); $request = m::mock(ServerRequestInterface::class); - $request->shouldReceive('getServerParams') - ->once() - ->andReturn([]); $request->shouldReceive('getCookieParams') ->once() ->andReturn(['foo' => 'bar']); @@ -337,7 +329,6 @@ public function testGetToken() * @uses PsrJwt\Auth\Authenticate * @uses PsrJwt\Parser\Parse * @uses PsrJwt\Parser\Bearer - * @uses PsrJwt\Parser\Server * @uses PsrJwt\Parser\Body * @uses PsrJwt\Parser\Cookie * @uses PsrJwt\Parser\Query @@ -349,9 +340,6 @@ public function testGetTokenNoToken() ->with('authorization') ->once() ->andReturn([]); - $request->shouldReceive('getServerParams') - ->once() - ->andReturn([]); $request->shouldReceive('getCookieParams') ->once() ->andReturn([]); diff --git a/tests/JwtAuthMiddlewareTest.php b/tests/JwtAuthMiddlewareTest.php index 55fbc3b..15fd4c7 100644 --- a/tests/JwtAuthMiddlewareTest.php +++ b/tests/JwtAuthMiddlewareTest.php @@ -123,22 +123,18 @@ public function testInvoke() * @uses PsrJwt\Parser\Parse * @uses PsrJwt\Parser\Body * @uses PsrJwt\Parser\Bearer - * @uses PsrJwt\Parser\Server * @uses PsrJwt\Parser\Query * @uses PsrJwt\Parser\Cookie */ public function testInvokeFail() { $request = m::mock(ServerRequestInterface::class); - $request->shouldReceive('getServerParams') - ->once() - ->andReturn(['jwt' => 'abc.abc.abc']); $request->shouldReceive('getCookieParams') ->once() - ->andReturn(['hello' => 'world']); + ->andReturn(['car' => 'park']); $request->shouldReceive('getQueryParams') ->once() - ->andReturn(['car' => 'park']); + ->andReturn(['jwt' => 'abc.abc.abc']); $request->shouldReceive('getParsedBody') ->twice() ->andReturn(['gary' => 'barlow']); diff --git a/tests/Parser/ServerTest.php b/tests/Parser/ServerTest.php deleted file mode 100644 index 4920237..0000000 --- a/tests/Parser/ServerTest.php +++ /dev/null @@ -1,45 +0,0 @@ - 'jwt']); - - $this->assertInstanceOf(Server::class, $server); - $this->assertInstanceOf(ParserInterface::class, $server); - } - - /** - * @covers PsrJwt\Parser\Server::parse - * @uses PsrJwt\Parser\Server::__construct - */ - public function testParse() - { - $request = m::mock(ServerRequestInterface::class); - $request->shouldReceive('getserverParams') - ->once() - ->andReturn(['jwt' => 'abc.def.ghi']); - - $server = new Server(['token_key' => 'jwt']); - $result = $server->parse($request); - - $this->assertSame('abc.def.ghi', $result); - } - - public function tearDown() - { - m::close(); - } -} From 779538637bb01d31ea6248d12889de855bf2e523 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Wed, 1 May 2019 22:10:15 +0100 Subject: [PATCH 20/22] Added phpstan mockery extension so I can run checks against tests folder without it losing its mind. --- .travis.yml | 2 +- composer.json | 1 + phpstan.neon | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 phpstan.neon diff --git a/.travis.yml b/.travis.yml index 3715dfa..871b3a1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ before_script: script: - vendor/bin/phpcs --standard=psr12 src - - vendor/bin/phpstan analyse -l 7 src + - vendor/bin/phpstan analyse -l 7 src tests - vendor/bin/phpmd src text ruleset.xml - vendor/bin/phpunit --coverage-clover=coverage.xml diff --git a/composer.json b/composer.json index 740cdb9..587e581 100644 --- a/composer.json +++ b/composer.json @@ -21,6 +21,7 @@ "require-dev": { "phpunit/phpunit": "^7.0", "phpstan/phpstan": "^0.10", + "phpstan/phpstan-mockery": "^0.10", "phpmd/phpmd": "2.6.*", "squizlabs/php_codesniffer": "^3.0", "mockery/mockery": "^1.2" diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..939b954 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,2 @@ +includes: + - vendor/phpstan/phpstan-mockery/extension.neon From 646ab284a919d6c39ffc3f0afb1915c7150e4d16 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Wed, 1 May 2019 22:15:03 +0100 Subject: [PATCH 21/22] Ran code sniff checks against tests folder, fixed issues and add check to travis ci. --- .travis.yml | 2 +- tests/JwtAuthMiddlewareTest.php | 7 ++++--- tests/Parser/ParseTest.php | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 871b3a1..6dffd6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ before_script: - travis_retry composer install --no-interaction --prefer-source --dev script: - - vendor/bin/phpcs --standard=psr12 src + - vendor/bin/phpcs --standard=psr12 src tests - vendor/bin/phpstan analyse -l 7 src tests - vendor/bin/phpmd src text ruleset.xml - vendor/bin/phpunit --coverage-clover=coverage.xml diff --git a/tests/JwtAuthMiddlewareTest.php b/tests/JwtAuthMiddlewareTest.php index 15fd4c7..c088822 100644 --- a/tests/JwtAuthMiddlewareTest.php +++ b/tests/JwtAuthMiddlewareTest.php @@ -100,7 +100,7 @@ public function testInvoke() $response = m::mock(ResponseInterface::class); - $next = function($request, $response) { + $next = function ($request, $response) { return $response; }; @@ -145,7 +145,7 @@ public function testInvokeFail() $response = m::mock(ResponseInterface::class); - $next = function($request, $response) { + $next = function ($request, $response) { return $response; }; @@ -159,7 +159,8 @@ public function testInvokeFail() $this->assertSame('Unauthorized: Signature is invalid.', $result->getReasonPhrase()); } - public function tearDown() { + public function tearDown() + { m::close(); } } diff --git a/tests/Parser/ParseTest.php b/tests/Parser/ParseTest.php index ad08967..3b20a11 100644 --- a/tests/Parser/ParseTest.php +++ b/tests/Parser/ParseTest.php @@ -75,7 +75,8 @@ public function testFindTokenFail() $this->assertEmpty($result); } - public function tearDown() { + public function tearDown() + { m::close(); } } From d7fe9f9fb209685651637f26f23ef0c4cb446a93 Mon Sep 17 00:00:00 2001 From: RobDWaller Date: Wed, 1 May 2019 22:34:12 +0100 Subject: [PATCH 22/22] Added more tests to JwtAuthMiddleware class to increase code coverage to 100%. --- tests/JwtAuthMiddlewareTest.php | 67 +++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/JwtAuthMiddlewareTest.php b/tests/JwtAuthMiddlewareTest.php index c088822..75a7867 100644 --- a/tests/JwtAuthMiddlewareTest.php +++ b/tests/JwtAuthMiddlewareTest.php @@ -7,11 +7,13 @@ use PsrJwt\Factory\Jwt; use PsrJwt\JwtAuthMiddleware; use PsrJwt\Auth\Authenticate; +use PsrJwt\Auth\Auth; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Server\MiddlewareInterface; use Mockery as m; +use ReflectionMethod; class JwtAuthMiddlewareTest extends TestCase { @@ -73,6 +75,49 @@ public function testProcess() $this->assertSame('Ok', $result->getReasonPhrase()); } + /** + * @covers PsrJwt\JwtAuthMiddleware::process + * @uses PsrJwt\JwtAuthMiddleware + * @uses PsrJwt\Auth\Authenticate + * @uses PsrJwt\Auth\Auth + * @uses PsrJwt\Factory\Jwt + * @uses PsrJwt\Parser\Parse + * @uses PsrJwt\Validation\Validate + * @uses PsrJwt\Parser\Bearer + * @uses PsrJwt\Parser\Body + * @uses PsrJwt\Parser\Cookie + * @uses PsrJwt\Parser\Query + */ + public function testProcessFail() + { + $request = m::mock(ServerRequestInterface::class); + $request->shouldReceive('getCookieParams') + ->once() + ->andReturn(['car' => 'park']); + $request->shouldReceive('getQueryParams') + ->once() + ->andReturn(['farm' => 'yard']); + $request->shouldReceive('getParsedBody') + ->twice() + ->andReturn(['gary' => 'barlow']); + $request->shouldReceive('getHeader') + ->with('authorization') + ->once() + ->andReturn([]); + + $handler = m::mock(RequestHandlerInterface::class); + + $authenticate = new Authenticate('jwt', 'Secret123!456$'); + + $process = new JwtAuthMiddleware($authenticate); + + $result = $process->process($request, $handler); + + $this->assertInstanceOf(ResponseInterface::class, $result); + $this->assertSame(400, $result->getStatusCode()); + $this->assertSame('Bad Request: JSON Web Token not set.', $result->getReasonPhrase()); + } + /** * @covers PsrJwt\JwtAuthMiddleware::__invoke * @uses PsrJwt\JwtAuthMiddleware::__construct @@ -159,6 +204,28 @@ public function testInvokeFail() $this->assertSame('Unauthorized: Signature is invalid.', $result->getReasonPhrase()); } + /** + * @covers PsrJwt\JwtAuthMiddleware::failResponse + * @uses PsrJwt\JwtAuthMiddleware + * @uses PsrJwt\Auth\Auth + * @uses PsrJwt\Auth\Authenticate + */ + public function testFailResponse() + { + $authenticate = new Authenticate('jwt', 'secret'); + $auth = new Auth(400, 'Bad Request'); + + $middleware = new JwtAuthMiddleware($authenticate); + + $method = new ReflectionMethod(JwtAuthMiddleware::class, 'failResponse'); + $method->setAccessible(true); + $result = $method->invokeArgs($middleware, [$auth]); + + $this->assertInstanceOf(ResponseInterface::class, $result); + $this->assertSame(400, $result->getStatusCode()); + $this->assertSame('Bad Request', $result->getReasonPhrase()); + } + public function tearDown() { m::close();