From 5d515aa2d28d068c2e44eb895cba4867e86b61a7 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Sun, 21 Jan 2024 22:55:14 +0100 Subject: [PATCH] allow tokens via header --- src/Guard.php | 6 +++++ tests/GuardTest.php | 56 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/src/Guard.php b/src/Guard.php index 9bd7df7..78780b8 100644 --- a/src/Guard.php +++ b/src/Guard.php @@ -446,6 +446,12 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface $value = $body[$this->getTokenValueKey()] ?? null; } + if ($name === null && $value === null) { + // DELETE request may not have a request body. Supply token by headers + $name = $request->getHeader($this->getTokenNameKey())[0] ?? null; + $value = $request->getHeader($this->getTokenValueKey())[0] ?? null; + } + if (in_array($request->getMethod(), ['POST', 'PUT', 'DELETE', 'PATCH'])) { $isValid = $this->validateToken((string) $name, (string) $value); if ($isValid && !$this->persistentTokenMode) { diff --git a/tests/GuardTest.php b/tests/GuardTest.php index 9955333..1e35dd4 100644 --- a/tests/GuardTest.php +++ b/tests/GuardTest.php @@ -115,6 +115,11 @@ public function testSetFailureHandler() ->willReturn([]) ->shouldBeCalledOnce(); + $requestProphecy + ->getHeader(Argument::type('string')) + ->willReturn([]) + ->shouldBeCalledTimes(2); + $requestHandlerProphecy = $this->prophesize(RequestHandlerInterface::class); $mw->process($requestProphecy->reveal(), $requestHandlerProphecy->reveal()); @@ -174,6 +179,11 @@ public function testDefaultFailureHandler() ->willReturn([]) ->shouldBeCalledOnce(); + $requestProphecy + ->getHeader(Argument::type('string')) + ->willReturn([]) + ->shouldBeCalledTimes(2); + $requestHandlerProphecy = $this->prophesize(RequestHandlerInterface::class); $response = $mw->process($requestProphecy->reveal(), $requestHandlerProphecy->reveal()); @@ -476,6 +486,7 @@ public function testProcessAppendsNewTokensWhenPersistentTokenModeIsOff() $requestProphecy = $this->prophesize(ServerRequestInterface::class); $requestProphecy->getParsedBody()->willReturn(null)->shouldBeCalledOnce(); + $requestProphecy->getHeader(Argument::type('string'))->willReturn([])->shouldBeCalledTimes(2); $requestProphecy ->getMethod() ->willReturn('GET') @@ -508,6 +519,7 @@ public function testProcessAppendsNewTokensWhenPersistentTokenModeIsOn() $requestProphecy = $this->prophesize(ServerRequestInterface::class); $requestProphecy->getParsedBody()->willReturn(null)->shouldBeCalledOnce(); + $requestProphecy->getHeader(Argument::type('string'))->willReturn([])->shouldBeCalledTimes(2); $requestProphecy ->getMethod() ->willReturn('GET') @@ -556,4 +568,48 @@ public function testCanGetLastKeyPairFromIterator() $unmaskedToken = $unmaskTokenMethod->invoke($mw, $keyPair['test_value']); $this->assertEquals('value2', $unmaskedToken); } + + public function testTokenFromHeaderOnDelete() + { + $storage = [ + 'test_name' => 'test_value123', + ]; + + $responseProphecy = $this->prophesize(ResponseInterface::class) + ->willImplement(ResponseInterface::class); + + $requestHandlerProphecy = $this->prophesize(RequestHandlerInterface::class); + $requestHandlerProphecy + ->handle(Argument::type(ServerRequestInterface::class)) + ->willReturn($responseProphecy->reveal()) + ->shouldBeCalledOnce(); + + $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); + + $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage); + + $requestProphecy = $this->prophesize(ServerRequestInterface::class); + $requestProphecy + ->getMethod() + ->willReturn('DELETE') + ->shouldBeCalledOnce(); + $requestProphecy + ->withAttribute(Argument::type('string'), Argument::type('string')) + ->willReturn($requestProphecy->reveal()) + ->shouldBeCalledTimes(2); + $requestProphecy + ->getParsedBody() + ->willReturn([]) + ->shouldBeCalledOnce(); + $requestProphecy + ->getHeader('test_name') + ->willReturn(['test_name']) + ->shouldBeCalledOnce(); + $requestProphecy + ->getHeader('test_value') + ->willReturn([$this->maskToken($mw, 'test_value123')]) + ->shouldBeCalledOnce(); + + $mw->process($requestProphecy->reveal(), $requestHandlerProphecy->reveal()); + } }