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