1<?php 2 3declare(strict_types=1); 4 5/* 6 * The MIT License (MIT) 7 * 8 * Copyright (c) 2014-2021 Spomky-Labs 9 * 10 * This software may be modified and distributed under the terms 11 * of the MIT license. See the LICENSE file for details. 12 */ 13 14namespace Webauthn\MetadataService; 15 16use Assert\Assertion; 17use Base64Url\Base64Url; 18use Psr\Http\Client\ClientInterface; 19use Psr\Http\Message\RequestFactoryInterface; 20use function Safe\json_decode; 21use function Safe\sprintf; 22 23class DistantSingleMetadata extends SingleMetadata 24{ 25 /** 26 * @var ClientInterface 27 */ 28 private $httpClient; 29 30 /** 31 * @var RequestFactoryInterface 32 */ 33 private $requestFactory; 34 35 /** 36 * @var array 37 */ 38 private $additionalHeaders; 39 40 /** 41 * @var string 42 */ 43 private $uri; 44 45 /** 46 * @var bool 47 */ 48 private $isBase64Encoded; 49 50 public function __construct(string $uri, bool $isBase64Encoded, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, array $additionalHeaders = []) 51 { 52 parent::__construct($uri, $isBase64Encoded); //Useless 53 $this->uri = $uri; 54 $this->isBase64Encoded = $isBase64Encoded; 55 $this->httpClient = $httpClient; 56 $this->requestFactory = $requestFactory; 57 $this->additionalHeaders = $additionalHeaders; 58 } 59 60 public function getMetadataStatement(): MetadataStatement 61 { 62 $payload = $this->fetch(); 63 $json = $this->isBase64Encoded ? Base64Url::decode($payload) : $payload; 64 $data = json_decode($json, true); 65 66 return MetadataStatement::createFromArray($data); 67 } 68 69 private function fetch(): string 70 { 71 $request = $this->requestFactory->createRequest('GET', $this->uri); 72 foreach ($this->additionalHeaders as $k => $v) { 73 $request = $request->withHeader($k, $v); 74 } 75 $response = $this->httpClient->sendRequest($request); 76 Assertion::eq(200, $response->getStatusCode(), sprintf('Unable to contact the server. Response code is %d', $response->getStatusCode())); 77 $content = $response->getBody()->getContents(); 78 Assertion::notEmpty($content, 'Unable to contact the server. The response has no content'); 79 80 return $content; 81 } 82} 83