From d04102f073a2e877fedcc649924dac5247ca44be Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Fri, 12 May 2023 11:04:03 -0700 Subject: [PATCH 1/4] fix: handle invalid http responses --- src/CachedKeySet.php | 6 ++++++ tests/CachedKeySetTest.php | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/CachedKeySet.php b/src/CachedKeySet.php index baf801f1..5061d559 100644 --- a/src/CachedKeySet.php +++ b/src/CachedKeySet.php @@ -178,6 +178,12 @@ private function keyIdExists(string $keyId): bool } $request = $this->httpFactory->createRequest('GET', $this->jwksUri); $jwksResponse = $this->httpClient->sendRequest($request); + if ($jwksResponse->getStatusCode() !== 200) { + throw new UnexpectedValueException( + (string) $jwksResponse->getBody(), + $jwksResponse->getStatusCode() + ); + } $this->keySet = $this->formatJwksForCache((string) $jwksResponse->getBody()); if (!isset($this->keySet[$keyId])) { diff --git a/tests/CachedKeySetTest.php b/tests/CachedKeySetTest.php index 9142fda6..6bb6964a 100644 --- a/tests/CachedKeySetTest.php +++ b/tests/CachedKeySetTest.php @@ -88,6 +88,40 @@ public function testOutOfBoundsThrowsException() $cachedKeySet['bar']; } + public function testInvalidHttpResponseThrowsException() + { + $this->expectException(\UnexpectedValueException::class); + $this->expectExceptionMessage('HTTP Error: URL not found'); + $this->expectExceptionCode(404); + + $body = $this->prophesize('Psr\Http\Message\StreamInterface'); + $body->__toString() + ->shouldBeCalledTimes(1) + ->willReturn('HTTP Error: URL not found'); + + $response = $this->prophesize('Psr\Http\Message\ResponseInterface'); + $response->getBody() + ->shouldBeCalledTimes(1) + ->willReturn($body->reveal()); + $response->getStatusCode() + ->shouldBeCalled() + ->willReturn(404); + + $http = $this->prophesize(ClientInterface::class); + $http->sendRequest(Argument::any()) + ->shouldBeCalledTimes(1) + ->willReturn($response->reveal()); + + $cachedKeySet = new CachedKeySet( + $this->testJwksUri, + $http->reveal(), + $this->getMockHttpFactory(), + $this->getMockEmptyCache() + ); + + isset($cachedKeySet[0]); + } + public function testWithExistingKeyId() { $cachedKeySet = new CachedKeySet( @@ -382,6 +416,9 @@ private function getMockHttpClient($testJwks, int $timesCalled = 1) $response->getBody() ->shouldBeCalledTimes($timesCalled) ->willReturn($body->reveal()); + $response->getStatusCode() + ->shouldBeCalledTimes($timesCalled) + ->willReturn(200); $http = $this->prophesize(ClientInterface::class); $http->sendRequest(Argument::any()) From ebe1ed9e5fe672b9c8961097126e97f62739adc3 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 14 Jun 2023 08:09:15 -0700 Subject: [PATCH 2/4] Update src/CachedKeySet.php Co-authored-by: croensch --- src/CachedKeySet.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/CachedKeySet.php b/src/CachedKeySet.php index 5061d559..75bc774a 100644 --- a/src/CachedKeySet.php +++ b/src/CachedKeySet.php @@ -180,7 +180,11 @@ private function keyIdExists(string $keyId): bool $jwksResponse = $this->httpClient->sendRequest($request); if ($jwksResponse->getStatusCode() !== 200) { throw new UnexpectedValueException( - (string) $jwksResponse->getBody(), + sprintf('Got bad HTTP status code %d %s for URI "%s"', + $jwksResponse->getStatusCode(), + $jwksResponse->getReasonPhrase(), + $this->jwksUri, + ), $jwksResponse->getStatusCode() ); } From 51198e1e0c56dfc1e9d0533272b00c49a602e5c9 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 14 Jun 2023 08:18:30 -0700 Subject: [PATCH 3/4] Update CachedKeySetTest.php --- tests/CachedKeySetTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/CachedKeySetTest.php b/tests/CachedKeySetTest.php index 6bb6964a..1df589b2 100644 --- a/tests/CachedKeySetTest.php +++ b/tests/CachedKeySetTest.php @@ -106,6 +106,9 @@ public function testInvalidHttpResponseThrowsException() $response->getStatusCode() ->shouldBeCalled() ->willReturn(404); + $response->getReasonPhrase() + ->shouldBeCalledTimes(1) + ->willReturn(''); $http = $this->prophesize(ClientInterface::class); $http->sendRequest(Argument::any()) From 41f82ee4e745784ddd6ab8eb6e9a5d12d3198c9e Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Wed, 14 Jun 2023 08:21:36 -0700 Subject: [PATCH 4/4] fix tests --- src/CachedKeySet.php | 2 +- tests/CachedKeySetTest.php | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/CachedKeySet.php b/src/CachedKeySet.php index 75bc774a..ee529f9f 100644 --- a/src/CachedKeySet.php +++ b/src/CachedKeySet.php @@ -180,7 +180,7 @@ private function keyIdExists(string $keyId): bool $jwksResponse = $this->httpClient->sendRequest($request); if ($jwksResponse->getStatusCode() !== 200) { throw new UnexpectedValueException( - sprintf('Got bad HTTP status code %d %s for URI "%s"', + sprintf('HTTP Error: %d %s for URI "%s"', $jwksResponse->getStatusCode(), $jwksResponse->getReasonPhrase(), $this->jwksUri, diff --git a/tests/CachedKeySetTest.php b/tests/CachedKeySetTest.php index 1df589b2..1e73af6d 100644 --- a/tests/CachedKeySetTest.php +++ b/tests/CachedKeySetTest.php @@ -91,24 +91,18 @@ public function testOutOfBoundsThrowsException() public function testInvalidHttpResponseThrowsException() { $this->expectException(\UnexpectedValueException::class); - $this->expectExceptionMessage('HTTP Error: URL not found'); + $this->expectExceptionMessage('HTTP Error: 404 URL not found'); $this->expectExceptionCode(404); $body = $this->prophesize('Psr\Http\Message\StreamInterface'); - $body->__toString() - ->shouldBeCalledTimes(1) - ->willReturn('HTTP Error: URL not found'); $response = $this->prophesize('Psr\Http\Message\ResponseInterface'); - $response->getBody() - ->shouldBeCalledTimes(1) - ->willReturn($body->reveal()); $response->getStatusCode() ->shouldBeCalled() ->willReturn(404); $response->getReasonPhrase() ->shouldBeCalledTimes(1) - ->willReturn(''); + ->willReturn('URL not found'); $http = $this->prophesize(ClientInterface::class); $http->sendRequest(Argument::any())