Lines
100.00%
21 / 21
Methods
100.00%
2 / 2
Classes
100.00%
1 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| discover | 100.00% | 20 / 20 | 100.00% | 1 / 1 | 5 | ||
| 27 | final readonly class OidcDiscoveryService | |
| 28 | { | |
| 29 | public function __construct( | |
| 30 | private HttpClientInterface $httpClient, | |
| 31 | ) { | |
| 32 | } | |
| 33 | ||
| 34 | /** | |
| 35 | * @throws ExceptionInterface | |
| 36 | */ | |
| 37 | public function discover(OidcProviderConfig $config): OidcDiscoveryDocument | |
| 38 | { | |
| 39 | $response = $this->httpClient->request('GET', $config->discoveryUrl); | |
| 40 | $content = $response->getContent(false); | |
| 41 | ||
| 42 | if ($response->getStatusCode() >= 400) { | |
| 43 | throw new RuntimeException(sprintf( | |
| 44 | 'OIDC discovery request failed for %s with status %d', | |
| 45 | $config->provider, | |
| 46 | $response->getStatusCode(), | |
| 47 | )); | |
| 48 | } | |
| 49 | ||
| 50 | try { | |
| 51 | $payload = json_decode($content, associative: true, depth: 512, flags: JSON_THROW_ON_ERROR); | |
| 52 | } catch (JsonException $exception) { | |
| 53 | throw new RuntimeException('OIDC discovery response is not valid JSON', previous: $exception); | |
| 54 | } | |
| 55 | ||
| 56 | if (!is_array($payload)) { | |
| 57 | throw new RuntimeException(sprintf( | |
| 58 | 'OIDC discovery response is not a JSON object/array, got %s', | |
| 59 | gettype($payload), | |
| 60 | )); | |
| 61 | } | |
| 62 | ||
| 63 | $normalizedPayload = []; | |
| 64 | foreach ($payload as $payloadKey => $payloadValue) { | |
| 65 | $normalizedPayload[(string) $payloadKey] = $payloadValue; | |
| 66 | } | |
| 67 | ||
| 68 | return OidcDiscoveryDocument::fromArray($normalizedPayload); | |
| 69 | } | |
| 70 | } |