diff --git a/src/CachedKeySet.php b/src/CachedKeySet.php index baf801f1..ee529f9f 100644 --- a/src/CachedKeySet.php +++ b/src/CachedKeySet.php @@ -178,6 +178,16 @@ 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( + sprintf('HTTP Error: %d %s for URI "%s"', + $jwksResponse->getStatusCode(), + $jwksResponse->getReasonPhrase(), + $this->jwksUri, + ), + $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..1e73af6d 100644 --- a/tests/CachedKeySetTest.php +++ b/tests/CachedKeySetTest.php @@ -88,6 +88,37 @@ public function testOutOfBoundsThrowsException() $cachedKeySet['bar']; } + public function testInvalidHttpResponseThrowsException() + { + $this->expectException(\UnexpectedValueException::class); + $this->expectExceptionMessage('HTTP Error: 404 URL not found'); + $this->expectExceptionCode(404); + + $body = $this->prophesize('Psr\Http\Message\StreamInterface'); + + $response = $this->prophesize('Psr\Http\Message\ResponseInterface'); + $response->getStatusCode() + ->shouldBeCalled() + ->willReturn(404); + $response->getReasonPhrase() + ->shouldBeCalledTimes(1) + ->willReturn('URL not found'); + + $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 +413,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())