IssuerMetadata   F
last analyzed

Complexity

Total Complexity 63

Size/Duplication

Total Lines 369
Duplicated Lines 0 %

Test Coverage

Coverage 97.83%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 82
dl 0
loc 369
ccs 135
cts 138
cp 0.9783
rs 3.36
c 1
b 0
f 0
wmc 63

62 Methods

Rating   Name   Duplication   Size   Complexity  
A getScopesSupported() 0 3 1
A jsonSerialize() 0 3 1
A getServiceDocumentation() 0 3 1
A isBackchannelLogoutSessionSupported() 0 3 1
A getAuthorizationEncryptionEncValuesSupported() 0 3 1
A getIntrospectionEncryptionAlgValuesSupported() 0 3 1
A isFrontchannelLogoutSupported() 0 3 1
A getUserinfoEndpoint() 0 3 1
A isRequestParameterSupported() 0 3 1
A getUserinfoEncryptionAlgValuesSupported() 0 3 1
A getIdTokenSigningAlgValuesSupported() 0 6 1
A getResponseModesSupported() 0 3 1
A getRequestObjectSigningAlgValuesSupported() 0 6 1
A getCheckSessionIframe() 0 3 1
A isBackchannelLogoutSupported() 0 3 1
A getTokenEndpoint() 0 3 1
A getOpPolicyUri() 0 3 1
A isTlsClientCertificateBoundAccessTokens() 0 3 1
A isRequireRequestUriRegistration() 0 3 1
A getRegistrationEndpoint() 0 3 1
A getTokenEndpointAuthSigningAlgValuesSupported() 0 6 1
A getRequestObjectEncryptionAlgValuesSupported() 0 3 1
A getIdTokenEncryptionAlgValuesSupported() 0 3 1
A getAcrValuesSupported() 0 3 1
A getAuthorizationSigningAlgValuesSupported() 0 3 1
A fromArray() 0 12 2
A getRequestObjectEncryptionEncValuesSupported() 0 3 1
A getIdTokenEncryptionEncValuesSupported() 0 3 1
A getIntrospectionEndpointAuthMethodsSupported() 0 3 1
A toArray() 0 3 1
A getMtlsEndpointAliases() 0 3 1
A getUserinfoEncryptionEncValuesSupported() 0 3 1
A isRequestUriParameterSupported() 0 3 1
A has() 0 3 1
A getDisplayValuesSupported() 0 3 1
A getClaimsSupported() 0 3 1
A getClaimTypesSupported() 0 3 1
A getEndSessionIframe() 0 3 1
A getRevocationEndpointAuthSigningAlgValuesSupported() 0 3 1
A getUiLocalesSupported() 0 3 1
A getSubjectTypesSupported() 0 3 1
A getIntrospectionEndpoint() 0 3 1
A getIntrospectionEncryptionEncValuesSupported() 0 3 1
A getOpTosUri() 0 3 1
A __construct() 0 15 1
A getRevocationEndpoint() 0 3 1
A getIssuer() 0 3 1
A getIntrospectionSigningAlgValuesSupported() 0 3 1
A getRevocationEndpointAuthMethodsSupported() 0 3 1
A get() 0 3 1
A isFrontchannelLogoutSessionSupported() 0 3 1
A getIntrospectionEndpointAuthSigningAlgValuesSupported() 0 3 1
A getUserinfoSigningAlgValuesSupported() 0 3 1
A getJwksUri() 0 3 1
A isClaimsParameterSupported() 0 3 1
A getGrantTypesSupported() 0 3 1
A getAuthorizationEncryptionAlgValuesSupported() 0 3 1
A getCodeChallengeMethodsSupported() 0 3 1
A getTokenEndpointAuthMethodsSupported() 0 3 1
A getClaimsLocalesSupported() 0 3 1
A getResponseTypesSupported() 0 3 1
A getAuthorizationEndpoint() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like IssuerMetadata often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use IssuerMetadata, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Facile\OpenIDClient\Issuer\Metadata;
6
7
use function array_diff;
8
use function array_filter;
9
use const ARRAY_FILTER_USE_BOTH;
10
use function array_key_exists;
11
use function array_keys;
12
use function array_merge;
13
use function count;
14
use Facile\OpenIDClient\Exception\InvalidArgumentException;
15
use function implode;
16
17
/**
18
 * @psalm-import-type IssuerMetadataObject from \Facile\JoseVerifier\Psalm\PsalmTypes
19
 */
20
final class IssuerMetadata implements IssuerMetadataInterface
21
{
22
    /**
23
     * @var array<string, mixed>
24
     * @psalm-var IssuerMetadataObject
25
     */
26
    private $metadata;
27
28
    /** @var string[] */
29
    private static $requiredKeys = [
30
        'issuer',
31
        'authorization_endpoint',
32
        'jwks_uri',
33
    ];
34
35
    /**
36
     * IssuerMetadata constructor.
37
     *
38
     * @param string $issuer
39
     * @param string $authorizationEndpoint
40
     * @param string $jwksUri
41
     * @param array<string, mixed> $claims
42
     */
43 69
    public function __construct(
44
        string $issuer,
45
        string $authorizationEndpoint,
46
        string $jwksUri,
47
        array $claims = []
48
    ) {
49
        $requiredClaims = [
50 69
            'issuer' => $issuer,
51 69
            'authorization_endpoint' => $authorizationEndpoint,
52 69
            'jwks_uri' => $jwksUri,
53
        ];
54
55
        /** @var IssuerMetadataObject $merged */
56 69
        $merged = array_merge($claims, $requiredClaims);
57 69
        $this->metadata = $merged;
0 ignored issues
show
Documentation Bug introduced by
It seems like $merged of type Facile\OpenIDClient\Issu...ta\IssuerMetadataObject is incompatible with the declared type array<string,mixed> of property $metadata.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
58 69
    }
59
60
    /**
61
     * @param array<string, mixed> $claims
62
     *
63
     * @return static
64
     *
65
     * @psalm-param IssuerMetadataObject $claims
66
     */
67 1
    public static function fromArray(array $claims): self
68
    {
69 1
        $missingKeys = array_diff(self::$requiredKeys, array_keys($claims));
70 1
        if (0 !== count($missingKeys)) {
71
            throw new InvalidArgumentException('Invalid issuer metadata. Missing keys: ' . implode(', ', $missingKeys));
72
        }
73
74 1
        return new static(
75 1
            $claims['issuer'],
76 1
            $claims['authorization_endpoint'],
77 1
            $claims['jwks_uri'],
78
            $claims
79
        );
80
    }
81
82 2
    public function getIssuer(): string
83
    {
84 2
        return $this->metadata['issuer'];
85
    }
86
87 2
    public function getAuthorizationEndpoint(): string
88
    {
89 2
        return $this->metadata['authorization_endpoint'];
90
    }
91
92 1
    public function getTokenEndpoint(): ?string
93
    {
94 1
        return $this->metadata['token_endpoint'] ?? null;
95
    }
96
97 1
    public function getUserinfoEndpoint(): ?string
98
    {
99 1
        return $this->metadata['userinfo_endpoint'] ?? null;
100
    }
101
102 1
    public function getRegistrationEndpoint(): ?string
103
    {
104 1
        return $this->metadata['registration_endpoint'] ?? null;
105
    }
106
107 2
    public function getJwksUri(): string
108
    {
109 2
        return $this->metadata['jwks_uri'];
110
    }
111
112 1
    public function getScopesSupported(): ?array
113
    {
114 1
        return $this->metadata['scopes_supported'] ?? null;
115
    }
116
117 1
    public function getResponseTypesSupported(): array
118
    {
119 1
        return $this->metadata['response_types_supported'];
120
    }
121
122 1
    public function getResponseModesSupported(): array
123
    {
124 1
        return $this->metadata['response_modes_supported'] ?? ['query', 'fragment'];
125
    }
126
127 1
    public function getGrantTypesSupported(): array
128
    {
129 1
        return $this->metadata['grant_types_supported'] ?? ['authorization_code', 'implicit'];
130
    }
131
132 1
    public function getAcrValuesSupported(): ?array
133
    {
134 1
        return $this->metadata['acr_values_supported'] ?? null;
135
    }
136
137 1
    public function getSubjectTypesSupported(): array
138
    {
139 1
        return $this->metadata['subject_types_supported'] ?? ['public'];
140
    }
141
142 1
    public function getDisplayValuesSupported(): ?array
143
    {
144 1
        return $this->metadata['display_values_supported'] ?? null;
145
    }
146
147 1
    public function getClaimTypesSupported(): array
148
    {
149 1
        return $this->metadata['claim_types_supported'] ?? ['normal'];
150
    }
151
152 1
    public function getClaimsSupported(): ?array
153
    {
154 1
        return $this->metadata['claims_supported'] ?? null;
155
    }
156
157 1
    public function getServiceDocumentation(): ?string
158
    {
159 1
        return $this->metadata['service_documentation'] ?? null;
160
    }
161
162 1
    public function getClaimsLocalesSupported(): ?array
163
    {
164 1
        return $this->metadata['claims_locales_supported'] ?? null;
165
    }
166
167 1
    public function getUiLocalesSupported(): ?array
168
    {
169 1
        return $this->metadata['ui_locales_supported'] ?? null;
170
    }
171
172 2
    public function isClaimsParameterSupported(): bool
173
    {
174 2
        return $this->metadata['claims_parameter_supported'] ?? false;
175
    }
176
177 2
    public function isRequestParameterSupported(): bool
178
    {
179 2
        return $this->metadata['request_parameter_supported'] ?? false;
180
    }
181
182 2
    public function isRequestUriParameterSupported(): bool
183
    {
184 2
        return $this->metadata['request_uri_parameter_supported'] ?? false;
185
    }
186
187 2
    public function isRequireRequestUriRegistration(): bool
188
    {
189 2
        return $this->metadata['require_request_uri_registration'] ?? true;
190
    }
191
192 1
    public function getOpPolicyUri(): ?string
193
    {
194 1
        return $this->metadata['op_policy_uri'] ?? null;
195
    }
196
197 1
    public function getOpTosUri(): ?string
198
    {
199 1
        return $this->metadata['op_tos_uri'] ?? null;
200
    }
201
202 1
    public function getCodeChallengeMethodsSupported(): ?array
203
    {
204 1
        return $this->metadata['code_challenge_methods_supported'] ?? null;
205
    }
206
207 1
    public function getTokenEndpointAuthMethodsSupported(): array
208
    {
209 1
        return $this->metadata['token_endpoint_auth_methods_supported'] ?? ['client_secret_basic'];
210
    }
211
212 1
    public function getTokenEndpointAuthSigningAlgValuesSupported(): array
213
    {
214
        /** @var list<non-empty-string> $default */
215 1
        $default = ['RS256'];
216
217 1
        return $this->metadata['token_endpoint_auth_signing_alg_values_supported'] ?? $default;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->metadata['...supported'] ?? $default could return the type Facile\OpenIDClient\Issuer\Metadata\list which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
218
    }
219
220 1
    public function getIdTokenSigningAlgValuesSupported(): array
221
    {
222
        /** @var list<non-empty-string> $default */
223 1
        $default = ['RS256'];
224
225 1
        return $this->metadata['id_token_signing_alg_values_supported'] ?? $default;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->metadata['...supported'] ?? $default could return the type Facile\OpenIDClient\Issuer\Metadata\list which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
226
    }
227
228 1
    public function getIdTokenEncryptionAlgValuesSupported(): array
229
    {
230 1
        return $this->metadata['id_token_encryption_alg_values_supported'] ?? [];
231
    }
232
233 1
    public function getIdTokenEncryptionEncValuesSupported(): array
234
    {
235 1
        return $this->metadata['id_token_encryption_enc_values_supported'] ?? [];
236
    }
237
238 1
    public function getUserinfoSigningAlgValuesSupported(): array
239
    {
240 1
        return $this->metadata['userinfo_signing_alg_values_supported'] ?? [];
241
    }
242
243 1
    public function getUserinfoEncryptionAlgValuesSupported(): array
244
    {
245 1
        return $this->metadata['userinfo_encryption_alg_values_supported'] ?? [];
246
    }
247
248 1
    public function getUserinfoEncryptionEncValuesSupported(): array
249
    {
250 1
        return $this->metadata['userinfo_encryption_enc_values_supported'] ?? [];
251
    }
252
253 1
    public function getAuthorizationSigningAlgValuesSupported(): array
254
    {
255 1
        return $this->metadata['authorization_signing_alg_values_supported'] ?? [];
256
    }
257
258 1
    public function getAuthorizationEncryptionAlgValuesSupported(): array
259
    {
260 1
        return $this->metadata['authorization_encryption_alg_values_supported'] ?? [];
261
    }
262
263 1
    public function getAuthorizationEncryptionEncValuesSupported(): array
264
    {
265 1
        return $this->metadata['authorization_encryption_enc_values_supported'] ?? [];
266
    }
267
268 1
    public function getIntrospectionEndpoint(): ?string
269
    {
270 1
        return $this->metadata['introspection_endpoint'] ?? null;
271
    }
272
273 1
    public function getIntrospectionEndpointAuthMethodsSupported(): array
274
    {
275 1
        return $this->metadata['introspection_endpoint_auth_methods_supported'] ?? [];
276
    }
277
278 1
    public function getIntrospectionEndpointAuthSigningAlgValuesSupported(): array
279
    {
280 1
        return $this->metadata['introspection_endpoint_auth_signing_alg_values_supported'] ?? [];
281
    }
282
283 1
    public function getIntrospectionSigningAlgValuesSupported(): array
284
    {
285 1
        return $this->metadata['introspection_signing_alg_values_supported'] ?? [];
286
    }
287
288 1
    public function getIntrospectionEncryptionAlgValuesSupported(): array
289
    {
290 1
        return $this->metadata['introspection_encryption_alg_values_supported'] ?? [];
291
    }
292
293 1
    public function getIntrospectionEncryptionEncValuesSupported(): array
294
    {
295 1
        return $this->metadata['introspection_encryption_enc_values_supported'] ?? [];
296
    }
297
298 1
    public function getRequestObjectSigningAlgValuesSupported(): array
299
    {
300
        /** @var list<non-empty-string> $default */
301 1
        $default = ['none', 'RS256'];
302
303 1
        return $this->metadata['request_object_signing_alg_values_supported'] ?? $default;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->metadata['...supported'] ?? $default could return the type Facile\OpenIDClient\Issuer\Metadata\list which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
304
    }
305
306 1
    public function getRequestObjectEncryptionAlgValuesSupported(): array
307
    {
308 1
        return $this->metadata['request_object_encryption_alg_values_supported'] ?? [];
309
    }
310
311 1
    public function getRequestObjectEncryptionEncValuesSupported(): array
312
    {
313 1
        return $this->metadata['request_object_encryption_enc_values_supported'] ?? [];
314
    }
315
316 1
    public function getRevocationEndpoint(): ?string
317
    {
318 1
        return $this->metadata['revocation_endpoint'] ?? null;
319
    }
320
321 1
    public function getRevocationEndpointAuthMethodsSupported(): array
322
    {
323 1
        return $this->metadata['revocation_endpoint_auth_methods_supported'] ?? [];
324
    }
325
326 1
    public function getRevocationEndpointAuthSigningAlgValuesSupported(): array
327
    {
328 1
        return $this->metadata['revocation_endpoint_auth_signing_alg_values_supported'] ?? [];
329
    }
330
331 1
    public function getCheckSessionIframe(): ?string
332
    {
333 1
        return $this->metadata['check_session_iframe'] ?? null;
334
    }
335
336 1
    public function getEndSessionIframe(): ?string
337
    {
338 1
        return $this->metadata['end_session_iframe'] ?? null;
339
    }
340
341 2
    public function isFrontchannelLogoutSupported(): bool
342
    {
343 2
        return $this->metadata['frontchannel_logout_supported'] ?? false;
344
    }
345
346 2
    public function isFrontchannelLogoutSessionSupported(): bool
347
    {
348 2
        return $this->metadata['frontchannel_logout_session_supported'] ?? false;
349
    }
350
351 2
    public function isBackchannelLogoutSupported(): bool
352
    {
353 2
        return $this->metadata['backchannel_logout_supported'] ?? false;
354
    }
355
356 2
    public function isBackchannelLogoutSessionSupported(): bool
357
    {
358 2
        return $this->metadata['backchannel_logout_session_supported'] ?? false;
359
    }
360
361 2
    public function isTlsClientCertificateBoundAccessTokens(): bool
362
    {
363 2
        return $this->metadata['tls_client_certificate_bound_access_tokens'] ?? false;
364
    }
365
366 1
    public function getMtlsEndpointAliases(): array
367
    {
368 1
        return $this->metadata['mtls_endpoint_aliases'] ?? [];
369
    }
370
371 1
    public function jsonSerialize(): array
372
    {
373 1
        return $this->metadata;
374
    }
375
376
    public function toArray(): array
377
    {
378
        return $this->metadata;
379
    }
380
381 1
    public function has(string $name): bool
382
    {
383 1
        return array_key_exists($name, $this->metadata);
384
    }
385
386 1
    public function get(string $name)
387
    {
388 1
        return $this->metadata[$name] ?? null;
389
    }
390
}
391