diff --git a/phpstan-baseline-8.0.neon b/phpstan-baseline-8.0.neon index 351923e7..39205d06 100644 --- a/phpstan-baseline-8.0.neon +++ b/phpstan-baseline-8.0.neon @@ -1,10 +1,5 @@ parameters: ignoreErrors: - - - message: "#^Parameter \\#1 \\$filename of function file_put_contents expects string, string\\|false given\\.$#" - count: 1 - path: src/lib/FieldTypeProcessor/BinaryInputProcessor.php - - message: "#^Access to an undefined property DOMNode\\:\\:\\$data\\.$#" count: 2 @@ -64,8 +59,3 @@ parameters: message: "#^Parameter \\#1 \\$string of function base64_encode expects string, string\\|false given\\.$#" count: 1 path: tests/bundle/Functional/BinaryContentTest.php - - - - message: "#^Parameter \\#1 \\$directory of function mkdir expects string, string\\|false given\\.$#" - count: 1 - path: tests/lib/FieldTypeProcessor/BinaryInputProcessorTest.php diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index d6e40792..3303b7b8 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5600,11 +5600,6 @@ parameters: count: 1 path: tests/lib/FieldTypeProcessor/BinaryInputProcessorTest.php - - - message: "#^Parameter \\#1 \\$filename of function unlink expects string, string\\|false given\\.$#" - count: 1 - path: tests/lib/FieldTypeProcessor/BinaryInputProcessorTest.php - - message: "#^Property Ibexa\\\\Tests\\\\Rest\\\\FieldTypeProcessor\\\\BinaryInputProcessorTest\\:\\:\\$tempDir has no type specified\\.$#" count: 1 @@ -8280,26 +8275,6 @@ parameters: count: 1 path: tests/lib/Server/Output/ValueObjectVisitor/ImageVariationTest.php - - - message: "#^Instantiated class Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\JWT not found\\.$#" - count: 1 - path: tests/lib/Server/Output/ValueObjectVisitor/JWTTest.php - - - - message: "#^Instantiated class Ibexa\\\\Rest\\\\Server\\\\Values\\\\JWT not found\\.$#" - count: 1 - path: tests/lib/Server/Output/ValueObjectVisitor/JWTTest.php - - - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\JWTTest\\:\\:internalGetVisitor\\(\\) has invalid return type Ibexa\\\\Rest\\\\Server\\\\Output\\\\ValueObjectVisitor\\\\JWT\\.$#" - count: 1 - path: tests/lib/Server/Output/ValueObjectVisitor/JWTTest.php - - - - message: "#^Static method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\ValueObjectVisitorBaseTest\\:\\:assertXMLTag\\(\\) invoked with 4 parameters, 2\\-3 required\\.$#" - count: 2 - path: tests/lib/Server/Output/ValueObjectVisitor/JWTTest.php - - message: "#^Method Ibexa\\\\Tests\\\\Rest\\\\Output\\\\ValueObjectVisitorBaseTest\\:\\:assertXMLTag\\(\\) invoked with 4 parameters, 2\\-3 required\\.$#" count: 2 diff --git a/src/bundle/Resources/config/input_parsers.yml b/src/bundle/Resources/config/input_parsers.yml index 225153fd..867e9222 100644 --- a/src/bundle/Resources/config/input_parsers.yml +++ b/src/bundle/Resources/config/input_parsers.yml @@ -82,11 +82,6 @@ services: tags: - { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.FieldDefinitionUpdate } - Ibexa\Rest\Server\Input\Parser\JWTInput: - parent: Ibexa\Rest\Server\Common\Parser - tags: - - { name: ibexa.rest.input.parser, mediaType: application/vnd.ibexa.api.JWTInput } - Ibexa\Rest\Server\Input\Parser\LocationCreate: parent: Ibexa\Rest\Server\Common\Parser class: Ibexa\Rest\Server\Input\Parser\LocationCreate diff --git a/src/bundle/Resources/config/routing.yml b/src/bundle/Resources/config/routing.yml index cd4e81b4..cd838e2f 100644 --- a/src/bundle/Resources/config/routing.yml +++ b/src/bundle/Resources/config/routing.yml @@ -1246,5 +1246,4 @@ ibexa.rest.load_bookmarks: # JWT ibexa.rest.create_token: path: /user/token/jwt - controller: Ibexa\Rest\Server\Controller\JWT::createToken methods: [POST] diff --git a/src/bundle/Resources/config/security.yml b/src/bundle/Resources/config/security.yml index c475d957..11466825 100644 --- a/src/bundle/Resources/config/security.yml +++ b/src/bundle/Resources/config/security.yml @@ -17,7 +17,11 @@ services: - '@?security.csrf.token_storage' - '@?request_stack' - Ibexa\Rest\Server\Security\EventListener\JWTAuthenticationSuccessSubscriber: + Ibexa\Rest\Server\Security\EventListener\JWT\AuthenticationSuccessSubscriber: + tags: + - { name: kernel.event_subscriber } + + Ibexa\Rest\Server\Security\EventListener\JWT\JsonLoginHeaderReplacingSubscriber: tags: - { name: kernel.event_subscriber } diff --git a/src/lib/Server/Controller/JWT.php b/src/lib/Server/Controller/JWT.php index ad5ee1f6..f1f705b3 100644 --- a/src/lib/Server/Controller/JWT.php +++ b/src/lib/Server/Controller/JWT.php @@ -9,28 +9,13 @@ namespace Ibexa\Rest\Server\Controller; use Ibexa\Rest\Server\Controller as RestController; -use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Routing\Generator\UrlGeneratorInterface; final class JWT extends RestController { - public function __construct(private readonly UrlGeneratorInterface $urlGenerator) + public function createToken(Request $request): void { - } - - public function createToken(Request $request): ?RedirectResponse - { - if ($request->headers->get('Content-Type') === 'application/json') { - return null; - } - - return new RedirectResponse( - $this->urlGenerator->generate('ibexa.rest.create_token'), - 307, - [ - 'Content-Type' => 'application/json', - ] - ); + //empty method for Symfony json_login authenticator which is used by Lexik/JWT under the hood + // for more detail refer to: https://symfony.com/bundles/LexikJWTAuthenticationBundle/current/index.html#symfony-5-3-and-higher } } diff --git a/src/lib/Server/Input/Parser/JWTInput.php b/src/lib/Server/Input/Parser/JWTInput.php deleted file mode 100644 index 0bc42d0c..00000000 --- a/src/lib/Server/Input/Parser/JWTInput.php +++ /dev/null @@ -1,30 +0,0 @@ - ['replaceJsonLoginHeader', 10], + ]; + } + + public function replaceJsonLoginHeader(RequestEvent $event): void + { + $request = $event->getRequest(); + if (!$request->headers->has(self::CONTENT_TYPE_HEADER)) { + return; + } + + if ($request->headers->get(self::CONTENT_TYPE_HEADER) !== 'application/vnd.ibexa.api.JWTInput+json') { + return; + } + + $request->headers->set(self::CONTENT_TYPE_HEADER, 'application/json'); + } +} diff --git a/src/lib/Server/Values/JWTInput.php b/src/lib/Server/Values/JWTInput.php deleted file mode 100644 index df30c224..00000000 --- a/src/lib/Server/Values/JWTInput.php +++ /dev/null @@ -1,20 +0,0 @@ -createRefreshRequest($session) ->withoutHeader('X-CSRF-Token'); $response = $this->sendHttpRequest($refreshRequest); + self::assertHttpResponseCodeEquals($response, 401); } diff --git a/tests/lib/Server/Input/Parser/JWTInputTest.php b/tests/lib/Server/Input/Parser/JWTInputTest.php deleted file mode 100644 index 2d25ee6d..00000000 --- a/tests/lib/Server/Input/Parser/JWTInputTest.php +++ /dev/null @@ -1,81 +0,0 @@ - $username, - 'password' => $password, - ]; - - $jwtInput = $this->internalGetParser(); - $result = $jwtInput->parse($inputArray, $this->getParsingDispatcherMock()); - - self::assertInstanceOf( - JWTInputValue::class, - $result, - 'JWTInput not created correctly.' - ); - - self::assertEquals( - $username, - $result->username - ); - - self::assertEquals( - $password, - $result->password - ); - } - - public function testParseExceptionOnEmptyPassword(): void - { - $username = 'johndoe'; - - $inputArray = [ - 'username' => $username, - ]; - - $this->expectException(Parser::class); - $this->expectExceptionMessage("Missing 'password' attribute for JWTInput."); - - $jwtInput = $this->internalGetParser(); - $jwtInput->parse($inputArray, $this->getParsingDispatcherMock()); - } - - public function testParseExceptionOnEmptyUsername(): void - { - $password = 'ibexa'; - - $inputArray = [ - 'password' => $password, - ]; - - $this->expectException(Parser::class); - $this->expectExceptionMessage("Missing 'username' attribute for JWTInput."); - - $jwtInput = $this->internalGetParser(); - $jwtInput->parse($inputArray, $this->getParsingDispatcherMock()); - } - - protected function internalGetParser(): JWTInput - { - return new JWTInput(); - } -} diff --git a/tests/lib/Server/Output/ValueObjectVisitor/JWTTest.php b/tests/lib/Server/Output/ValueObjectVisitor/JWTTest.php deleted file mode 100644 index 2cbbd0ea..00000000 --- a/tests/lib/Server/Output/ValueObjectVisitor/JWTTest.php +++ /dev/null @@ -1,83 +0,0 @@ -getVisitor(); - $generator = $this->getGenerator(); - - $generator->startDocument(null); - - $token = new JWTValue('abc'); - - $visitor->visit( - $this->getVisitorMock(), - $generator, - $token - ); - - $result = $generator->endDocument(null); - - self::assertNotNull($result); - - return $result; - } - - /** - * @param string $result - * - * @depends testVisit - */ - public function testResultContainsTokenTagWithTokenAttribute(string $result): void - { - self::assertXMLTag( - [ - 'tag' => 'JWT', - 'attributes' => [ - 'token' => 'abc', - ], - ], - $result, - 'Missing token attributes.', - false - ); - } - - /** - * @param string $result - * - * @depends testVisit - */ - public function testResultContainsTokenTagWithMediaTypeAttribute(string $result): void - { - self::assertXMLTag( - [ - 'tag' => 'JWT', - 'attributes' => [ - 'media-type' => 'application/vnd.ibexa.api.JWT+xml', - ], - ], - $result, - 'Missing media-type attribute.', - false - ); - } - - protected function internalGetVisitor(): JWT - { - return new JWT(); - } -}