Lines 100.00% 21 / 21
Methods 100.00% 2 / 2
Classes 100.00% 1 / 1
Covered by tests of size
Name Lines Methods CRAP
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 discover 100.00% 20 / 20 100.00% 1 / 1 5
27final 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}