Failed Conditions
Push — master ( dedff1...43e85c )
by Florent
04:53
created

JoseCollector::collectJWKSet()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.2
c 0
b 0
f 0
cc 4
eloc 10
nc 3
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2014-2017 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
14
namespace Jose\Bundle\JoseFramework\DataCollector;
15
16
use Jose\Component\Checker\ClaimCheckerManager;
17
use Jose\Component\Checker\ClaimCheckerManagerFactory;
18
use Jose\Component\Checker\HeaderCheckerManager;
19
use Jose\Component\Checker\HeaderCheckerManagerFactory;
20
use Jose\Component\Core\Algorithm;
21
use Jose\Component\Core\AlgorithmManagerFactory;
22
use Jose\Component\Core\JWK;
23
use Jose\Component\Core\JWKSet;
24
use Jose\Component\Encryption\Algorithm\ContentEncryptionAlgorithm;
25
use Jose\Component\Encryption\Algorithm\KeyEncryptionAlgorithm;
26
use Jose\Component\Encryption\Compression\CompressionMethodManagerFactory;
27
use Jose\Component\Encryption\JWEBuilder;
28
use Jose\Component\Encryption\JWEDecrypter;
29
use Jose\Component\Encryption\Serializer\JWESerializerManagerFactory;
30
use Jose\Component\KeyManagement\KeyAnalyzer\KeyAnalyzerManager;
31
use Jose\Component\Signature\Algorithm\SignatureAlgorithm;
32
use Jose\Component\Signature\JWSBuilder;
33
use Jose\Component\Signature\JWSVerifier;
34
use Jose\Component\Signature\Serializer\JWSSerializerManagerFactory;
35
use Symfony\Component\HttpFoundation\Request;
36
use Symfony\Component\HttpFoundation\Response;
37
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
38
39
final class JoseCollector extends DataCollector
40
{
41
    /**
42
     * @var AlgorithmManagerFactory
43
     */
44
    private $algorithmManagerFactory;
45
46
    /**
47
     * @var CompressionMethodManagerFactory|null
48
     */
49
    private $compressionMethodManagerFactory;
50
51
    /**
52
     * @var JWSSerializerManagerFactory|null
53
     */
54
    private $jwsSerializerManagerFactory;
55
56
    /**
57
     * @var JWESerializerManagerFactory|null
58
     */
59
    private $jweSerializerManagerFactory;
60
61
    /**
62
     * @var KeyAnalyzerManager|null
63
     */
64
    private $jwkAnalyzerManager;
65
66
    /**
67
     * @var ClaimCheckerManagerFactory|null
68
     */
69
    private $claimCheckerManagerFactory;
70
71
    /**
72
     * @var HeaderCheckerManagerFactory|null
73
     */
74
    private $headerCheckerManagerFactory;
75
76
    /**
77
     * JoseCollector constructor.
78
     *
79
     * @param AlgorithmManagerFactory              $algorithmManagerFactory
80
     * @param CompressionMethodManagerFactory|null $compressionMethodManagerFactory
81
     * @param JWSSerializerManagerFactory|null     $jwsSerializerManagerFactory
82
     * @param JWESerializerManagerFactory|null     $jweSerializerManagerFactory
83
     * @param KeyAnalyzerManager|null              $jwkAnalyzerManager
84
     * @param ClaimCheckerManagerFactory|null      $claimCheckerManagerFactory
85
     * @param HeaderCheckerManagerFactory|null     $headerCheckerManagerFactory
86
     */
87
    public function __construct(
88
        AlgorithmManagerFactory $algorithmManagerFactory,
89
        ?CompressionMethodManagerFactory $compressionMethodManagerFactory = null,
90
        ?JWSSerializerManagerFactory $jwsSerializerManagerFactory = null,
91
        ?JWESerializerManagerFactory $jweSerializerManagerFactory = null,
92
        ?KeyAnalyzerManager $jwkAnalyzerManager = null,
93
        ?ClaimCheckerManagerFactory $claimCheckerManagerFactory = null,
94
        ?HeaderCheckerManagerFactory $headerCheckerManagerFactory = null
95
    ) {
96
        $this->data = [];
97
        $this->algorithmManagerFactory = $algorithmManagerFactory;
98
        $this->compressionMethodManagerFactory = $compressionMethodManagerFactory;
99
        $this->jwsSerializerManagerFactory = $jwsSerializerManagerFactory;
100
        $this->jweSerializerManagerFactory = $jweSerializerManagerFactory;
101
        $this->jwkAnalyzerManager = $jwkAnalyzerManager;
102
        $this->claimCheckerManagerFactory = $claimCheckerManagerFactory;
103
        $this->headerCheckerManagerFactory = $headerCheckerManagerFactory;
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109
    public function collect(Request $request, Response $response, \Exception $exception = null)
110
    {
111
        $this->collectSupportedAlgorithms();
112
        $this->collectSupportedHeaderCheckers();
113
        $this->collectSupportedClaimCheckers();
114
        $this->collectSupportedCompressionMethods();
115
        $this->collectSupportedJWSSerializations();
116
        $this->collectSupportedJWESerializations();
117
        $this->collectSupportedJWSBuilders();
118
        $this->collectSupportedJWSVerifiers();
119
        $this->collectSupportedJWEBuilders();
120
        $this->collectSupportedJWEDecrypters();
121
        $this->collectJWK();
122
        $this->collectJWKSet();
123
    }
124
125
    /**
126
     * @return array
127
     */
128
    public function getAlgorithmDetails(): array
129
    {
130
        return $this->data['algorithms'];
131
    }
132
133
    /**
134
     * @return int
135
     */
136
    public function countSignatureAlgorithms(): int
137
    {
138
        return $this->data['types']['signature'];
139
    }
140
141
    /**
142
     * @return int
143
     */
144
    public function countKeyEncryptionAlgorithms(): int
145
    {
146
        return $this->data['types']['key_encryption'];
147
    }
148
149
    /**
150
     * @return int
151
     */
152
    public function countContentEncryptionAlgorithms(): int
153
    {
154
        return $this->data['types']['content_encryption'];
155
    }
156
157
    /**
158
     * @return array
159
     */
160
    public function getCompressionMethodDetails(): array
161
    {
162
        return $this->data['compression_methods'];
163
    }
164
165
    /**
166
     * @return array
167
     */
168
    public function getJWSSerializationDetails(): array
169
    {
170
        return $this->data['jws_serialization'];
171
    }
172
173
    /**
174
     * @return array
175
     */
176
    public function getJWESerializationDetails(): array
177
    {
178
        return $this->data['jwe_serialization'];
179
    }
180
181
    /**
182
     * @return array
183
     */
184
    public function getJWKs(): array
185
    {
186
        return $this->data['jwk'];
187
    }
188
189
    /**
190
     * @return array
191
     */
192
    public function getJWKSets(): array
193
    {
194
        return $this->data['jwkset'];
195
    }
196
197
    /**
198
     * @return array
199
     */
200
    public function getJWSBuilders(): array
201
    {
202
        return $this->data['jws_builders'];
203
    }
204
205
    /**
206
     * @return array
207
     */
208
    public function getJWSVerifiers(): array
209
    {
210
        return $this->data['jws_verifiers'];
211
    }
212
213
    /**
214
     * @return array
215
     */
216
    public function getJWEBuilders(): array
217
    {
218
        return $this->data['jwe_builders'];
219
    }
220
221
    /**
222
     * @return array
223
     */
224
    public function getJWEDecrypters(): array
225
    {
226
        return $this->data['jwe_decrypters'];
227
    }
228
229
    /**
230
     * @return array
231
     */
232
    public function getHeaderCheckers(): array
233
    {
234
        return $this->data['header_checkers'];
235
    }
236
237
    /**
238
     * @return array
239
     */
240
    public function getHeaderCheckerManagers(): array
241
    {
242
        return $this->headerCheckerManagers;
243
    }
244
245
    /**
246
     * @return array
247
     */
248
    public function getClaimCheckers(): array
249
    {
250
        return $this->data['claim_checkers'];
251
    }
252
253
    /**
254
     * @return array
255
     */
256
    public function getClaimCheckerManagers(): array
257
    {
258
        return $this->claimCheckerManagers;
259
    }
260
261
    /**
262
     * {@inheritdoc}
263
     */
264
    public function getName()
265
    {
266
        return 'jose_collector';
267
    }
268
269
    private function collectSupportedHeaderCheckers()
270
    {
271
        $this->data['header_checkers'] = [];
272
        if (null !== $this->headerCheckerManagerFactory) {
273
            $aliases = $this->headerCheckerManagerFactory->all();
274
            foreach ($aliases as $alias => $checker) {
275
                $this->data['header_checkers'][$alias] = [
276
                    'header' => $checker->supportedHeader(),
277
                    'protected' => $checker->protectedHeaderOnly(),
278
                ];
279
            }
280
        }
281
    }
282
283
    private function collectSupportedClaimCheckers()
284
    {
285
        $this->data['claim_checkers'] = [];
286
        if (null !== $this->headerCheckerManagerFactory) {
287
            $aliases = $this->claimCheckerManagerFactory->all();
288
            foreach ($aliases as $alias => $checker) {
289
                $this->data['claim_checkers'][$alias] = [
290
                    'claim' => $checker->supportedClaim(),
291
                ];
292
            }
293
        }
294
    }
295
296
    private function collectSupportedAlgorithms()
297
    {
298
        $algorithms = $this->algorithmManagerFactory->all();
299
        $this->data['algorithms'] = [];
300
        $signatureAlgorithms = 0;
301
        $keyEncryptionAlgorithms = 0;
302
        $contentEncryptionAlgorithms = 0;
303
        foreach ($algorithms as $alias => $algorithm) {
304
            $type = $this->getAlgorithmType($algorithm, $signatureAlgorithms, $keyEncryptionAlgorithms, $contentEncryptionAlgorithms);
305
            if (!array_key_exists($type, $this->data['algorithms'])) {
306
                $this->data['algorithms'][$type] = [];
307
            }
308
            $this->data['algorithms'][$type][$alias] = [
309
                'name' => $algorithm->name(),
310
            ];
311
        }
312
313
        $this->data['types'] = [
314
            'signature' => $signatureAlgorithms,
315
            'key_encryption' => $keyEncryptionAlgorithms,
316
            'content_encryption' => $contentEncryptionAlgorithms,
317
        ];
318
    }
319
320
    /**
321
     * @param Algorithm $algorithm
322
     * @param int       $signatureAlgorithms
323
     * @param int       $keyEncryptionAlgorithms
324
     * @param int       $contentEncryptionAlgorithms
325
     *
326
     * @return string
327
     */
328
    private function getAlgorithmType(Algorithm $algorithm, int &$signatureAlgorithms, int &$keyEncryptionAlgorithms, int &$contentEncryptionAlgorithms): string
329
    {
330
        switch (true) {
331
            case $algorithm instanceof SignatureAlgorithm:
332
                $signatureAlgorithms++;
333
334
                return 'Signature';
335
            case $algorithm instanceof KeyEncryptionAlgorithm:
336
                $keyEncryptionAlgorithms++;
337
338
                return 'Key Encryption';
339
            case $algorithm instanceof ContentEncryptionAlgorithm:
340
                $contentEncryptionAlgorithms++;
341
342
                return 'Content Encryption';
343
            default:
344
                return 'Unknown';
345
        }
346
    }
347
348
    private function collectSupportedCompressionMethods()
349
    {
350
        $this->data['compression_methods'] = [];
351
        if (null === $this->compressionMethodManagerFactory) {
352
            return;
353
        }
354
        $compressionMethods = $this->compressionMethodManagerFactory->all();
355
        foreach ($compressionMethods as $alias => $compressionMethod) {
356
            $this->data['compression_methods'][$alias] = $compressionMethod->name();
357
        }
358
    }
359
360
    private function collectSupportedJWSSerializations()
361
    {
362
        $this->data['jws_serialization'] = [];
363
        if (null === $this->jwsSerializerManagerFactory) {
364
            return;
365
        }
366
        $serializers = $this->jwsSerializerManagerFactory->all();
367
        foreach ($serializers as $serializer) {
368
            $this->data['jws_serialization'][$serializer->name()] = $serializer->displayName();
369
        }
370
    }
371
372
    private function collectSupportedJWESerializations()
373
    {
374
        $this->data['jwe_serialization'] = [];
375
        if (null === $this->jweSerializerManagerFactory) {
376
            return;
377
        }
378
        $serializers = $this->jweSerializerManagerFactory->all();
379
        foreach ($serializers as $serializer) {
380
            $this->data['jwe_serialization'][$serializer->name()] = $serializer->displayName();
381
        }
382
    }
383
384
    private function collectSupportedJWSBuilders()
385
    {
386
        $this->data['jws_builders'] = [];
387
        foreach ($this->jwsBuilders as $id => $jwsBuilder) {
388
            $this->data['jws_builders'][$id] = [
389
                'signature_algorithms' => $jwsBuilder->getSignatureAlgorithmManager()->list(),
390
            ];
391
        }
392
    }
393
394
    private function collectSupportedJWSVerifiers()
395
    {
396
        $this->data['jws_verifiers'] = [];
397
        foreach ($this->jwsVerifiers as $id => $jwsVerifier) {
398
            $this->data['jws_verifiers'][$id] = [
399
                'signature_algorithms' => $jwsVerifier->getSignatureAlgorithmManager()->list(),
400
            ];
401
        }
402
    }
403
404
    private function collectSupportedJWEBuilders()
405
    {
406
        $this->data['jwe_builders'] = [];
407
        foreach ($this->jweBuilders as $id => $jweBuilder) {
408
            $this->data['jwe_builders'][$id] = [
409
                'key_encryption_algorithms' => $jweBuilder->getKeyEncryptionAlgorithmManager()->list(),
410
                'content_encryption_algorithms' => $jweBuilder->getContentEncryptionAlgorithmManager()->list(),
411
                'compression_methods' => $jweBuilder->getCompressionMethodManager()->list(),
412
            ];
413
        }
414
    }
415
416
    private function collectSupportedJWEDecrypters()
417
    {
418
        $this->data['jwe_decrypters'] = [];
419
        foreach ($this->jweDecrypters as $id => $jweDecrypter) {
420
            $this->data['jwe_decrypters'][$id] = [
421
                'key_encryption_algorithms' => $jweDecrypter->getKeyEncryptionAlgorithmManager()->list(),
422
                'content_encryption_algorithms' => $jweDecrypter->getContentEncryptionAlgorithmManager()->list(),
423
                'compression_methods' => $jweDecrypter->getCompressionMethodManager()->list(),
424
            ];
425
        }
426
    }
427
428
    private function collectJWK()
429
    {
430
        $this->data['jwk'] = [];
431
        foreach ($this->jwks as $id => $jwk) {
432
            $this->data['jwk'][$id] = [
433
                'jwk' => $jwk,
434
                'analyze' => null === $this->jwkAnalyzerManager ? [] : $this->jwkAnalyzerManager->analyze($jwk),
435
            ];
436
        }
437
    }
438
439
    private function collectJWKSet()
440
    {
441
        $this->data['jwkset'] = [];
442
        foreach ($this->jwksets as $id => $jwkset) {
443
            $analyze = [];
444
            if (null !== $this->jwkAnalyzerManager) {
445
                foreach ($jwkset as $kid => $jwk) {
446
                    $analyze[$kid] = $this->jwkAnalyzerManager->analyze($jwk);
0 ignored issues
show
Bug introduced by
It seems like $jwk defined by $jwk on line 445 can be null; however, Jose\Component\KeyManage...lyzerManager::analyze() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
447
                }
448
            }
449
            $this->data['jwkset'][$id] = [
450
                'jwkset' => $jwkset,
451
                'analyze' => $analyze,
452
            ];
453
        }
454
    }
455
456
    /**
457
     * @var HeaderCheckerManager[]
458
     */
459
    private $headerCheckerManagers = [];
460
461
    /**
462
     * @param string               $id
463
     * @param HeaderCheckerManager $headerCheckerManager
464
     */
465
    public function addHeaderCheckerManager(string $id, HeaderCheckerManager $headerCheckerManager)
466
    {
467
        $this->headerCheckerManagers[$id] = $headerCheckerManager;
468
    }
469
470
    /**
471
     * @var ClaimCheckerManager[]
472
     */
473
    private $claimCheckerManagers = [];
474
475
    /**
476
     * @param string              $id
477
     * @param ClaimCheckerManager $claimCheckerManager
478
     */
479
    public function addClaimCheckerManager(string $id, ClaimCheckerManager $claimCheckerManager)
480
    {
481
        $this->claimCheckerManagers[$id] = $claimCheckerManager;
482
    }
483
484
    /**
485
     * @var JWSBuilder[]
486
     */
487
    private $jwsBuilders = [];
488
489
    /**
490
     * @param string     $id
491
     * @param JWSBuilder $jwsBuilder
492
     */
493
    public function addJWSBuilder(string $id, JWSBuilder $jwsBuilder)
494
    {
495
        $this->jwsBuilders[$id] = $jwsBuilder;
496
    }
497
498
    /**
499
     * @var JWSVerifier[]
500
     */
501
    private $jwsVerifiers = [];
502
503
    /**
504
     * @param string      $id
505
     * @param JWSVerifier $jwsVerifier
506
     */
507
    public function addJWSVerifier(string $id, JWSVerifier $jwsVerifier)
508
    {
509
        $this->jwsVerifiers[$id] = $jwsVerifier;
510
    }
511
512
    /**
513
     * @var JWEBuilder[]
514
     */
515
    private $jweBuilders = [];
516
517
    /**
518
     * @param string     $id
519
     * @param JWEBuilder $jweBuilder
520
     */
521
    public function addJWEBuilder(string $id, JWEBuilder $jweBuilder)
522
    {
523
        $this->jweBuilders[$id] = $jweBuilder;
524
    }
525
526
    /**
527
     * @var JWEDecrypter[]
528
     */
529
    private $jweDecrypters = [];
530
531
    /**
532
     * @param string       $id
533
     * @param JWEDecrypter $jweDecrypter
534
     */
535
    public function addJWEDecrypter(string $id, JWEDecrypter $jweDecrypter)
536
    {
537
        $this->jweDecrypters[$id] = $jweDecrypter;
538
    }
539
540
    /**
541
     * @var JWK[]
542
     */
543
    private $jwks = [];
544
545
    /**
546
     * @param string $id
547
     * @param JWK    $jwk
548
     */
549
    public function addJWK(string $id, JWK $jwk)
550
    {
551
        $this->jwks[$id] = $jwk;
552
    }
553
554
    /**
555
     * @var JWKSet[]
556
     */
557
    private $jwksets = [];
558
559
    /**
560
     * @param string $id
561
     * @param JWKSet $jwkset
562
     */
563
    public function addJWKSet(string $id, JWKSet $jwkset)
564
    {
565
        $this->jwksets[$id] = $jwkset;
566
    }
567
}
568