Failed Conditions
Push — master ( ea06df...34d59f )
by Florent
10:18
created

JoseCollector::collectSupportedJWSBuilders()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 5
nc 2
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\AlgorithmInterface;
17
use Jose\Component\Core\AlgorithmManagerFactory;
18
use Jose\Component\Core\JWK;
19
use Jose\Component\Core\JWKSet;
20
use Jose\Component\Encryption\Algorithm\ContentEncryptionAlgorithmInterface;
21
use Jose\Component\Encryption\Algorithm\KeyEncryptionAlgorithmInterface;
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\JWKAnalyzerManager;
27
use Jose\Component\Signature\Algorithm\SignatureAlgorithmInterface;
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 JWKAnalyzerManager|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 JWKAnalyzerManager|null              $jwkAnalyzerManager
70
     */
71
    public function __construct(AlgorithmManagerFactory $algorithmManagerFactory, ?CompressionMethodManagerFactory $compressionMethodManagerFactory = null, ?JWSSerializerManagerFactory $jwsSerializerManagerFactory = null, ?JWESerializerManagerFactory $jweSerializerManagerFactory = null, ?JWKAnalyzerManager $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
     * {@inheritdoc}
156
     */
157
    public function getName()
158
    {
159
        return 'jose_collector';
160
    }
161
162
    private function collectSupportedAlgorithms()
163
    {
164
        $algorithms = $this->algorithmManagerFactory->all();
165
        $this->data['algorithms'] = [];
166
        $signatureAlgorithms = 0;
167
        $keyEncryptionAlgorithms = 0;
168
        $contentEncryptionAlgorithms = 0;
169
        foreach ($algorithms as $alias => $algorithm) {
170
            $type = $this->getAlgorithmType($algorithm, $signatureAlgorithms, $keyEncryptionAlgorithms, $contentEncryptionAlgorithms);
171
            if (!array_key_exists($type, $this->data['algorithms'])) {
172
                $this->data['algorithms'][$type] = [];
173
            }
174
            $this->data['algorithms'][$type][$alias] = [
175
                'name' => $algorithm->name(),
176
            ];
177
        }
178
179
        $this->data['types'] = [
180
            'signature' => $signatureAlgorithms,
181
            'key_encryption' => $keyEncryptionAlgorithms,
182
            'content_encryption' => $contentEncryptionAlgorithms,
183
        ];
184
    }
185
186
    /**
187
     * @param AlgorithmInterface $algorithm
188
     * @param int                $signatureAlgorithms
189
     * @param int                $keyEncryptionAlgorithms
190
     * @param int                $contentEncryptionAlgorithms
191
     *
192
     * @return string
193
     */
194
    private function getAlgorithmType(AlgorithmInterface $algorithm, int &$signatureAlgorithms, int &$keyEncryptionAlgorithms, int &$contentEncryptionAlgorithms): string
195
    {
196
        switch (true) {
197
            case $algorithm instanceof SignatureAlgorithmInterface:
198
                $signatureAlgorithms++;
199
200
                return 'Signature';
201
            case $algorithm instanceof KeyEncryptionAlgorithmInterface:
202
                $keyEncryptionAlgorithms++;
203
204
                return 'Key Encryption';
205
            case $algorithm instanceof ContentEncryptionAlgorithmInterface:
206
                $contentEncryptionAlgorithms++;
207
208
                return 'Content Encryption';
209
            default:
210
                return 'Unknown';
211
        }
212
    }
213
214
    private function collectSupportedCompressionMethods()
215
    {
216
        $this->data['compression_methods'] = [];
217
        if (null === $this->compressionMethodManagerFactory) {
218
            return;
219
        }
220
        $compressionMethods = $this->compressionMethodManagerFactory->all();
221
        foreach ($compressionMethods as $alias => $compressionMethod) {
222
            $this->data['compression_methods'][$alias] = $compressionMethod->name();
223
        }
224
    }
225
226
    private function collectSupportedJWSSerializations()
227
    {
228
        $this->data['jws_serialization'] = [];
229
        if (null === $this->jwsSerializerManagerFactory) {
230
            return;
231
        }
232
        $serializers = $this->jwsSerializerManagerFactory->all();
233
        foreach ($serializers as $serializer) {
234
            $this->data['jws_serialization'][$serializer->name()] = $serializer->displayName();
235
        }
236
    }
237
238
    private function collectSupportedJWESerializations()
239
    {
240
        $this->data['jwe_serialization'] = [];
241
        if (null === $this->jweSerializerManagerFactory) {
242
            return;
243
        }
244
        $serializers = $this->jweSerializerManagerFactory->all();
245
        foreach ($serializers as $serializer) {
246
            $this->data['jwe_serialization'][$serializer->name()] = $serializer->displayName();
247
        }
248
    }
249
250
    private function collectSupportedJWSBuilders()
251
    {
252
        $this->data['jws_builders'] = [];
253
        foreach ($this->jwsBuilders as $id => $jwsBuilder) {
254
            $this->data['jws_builders'][$id] = [
255
                'signature_algorithms' => $jwsBuilder->getSignatureAlgorithmManager()->list(),
256
            ];
257
        }
258
    }
259
260
    private function collectSupportedJWSVerifiers()
261
    {
262
        $this->data['jws_verifiers'] = [];
263
        foreach ($this->jwsVerifiers as $id => $jwsVerifier) {
264
            $this->data['jws_verifiers'][$id] = [
265
                'signature_algorithms' => $jwsVerifier->getSignatureAlgorithmManager()->list(),
266
                //Add header checkers
267
            ];
268
        }
269
    }
270
271
    private function collectSupportedJWEBuilders()
272
    {
273
        $this->data['jwe_builders'] = [];
274
        foreach ($this->jweBuilders as $id => $jweBuilder) {
275
            $this->data['jwe_builders'][$id] = [
276
                'key_encryption_algorithms' => $jweBuilder->getKeyEncryptionAlgorithmManager()->list(),
277
                'content_encryption_algorithms' => $jweBuilder->getContentEncryptionAlgorithmManager()->list(),
278
                'compression_methods' => $jweBuilder->getCompressionMethodManager()->list(),
279
                //Add header checkers
280
            ];
281
        }
282
    }
283
284
    private function collectSupportedJWEDecrypters()
285
    {
286
        $this->data['jwe_decrypters'] = [];
287
        foreach ($this->jweDecrypters as $id => $jweDecrypter) {
288
            $this->data['jwe_decrypters'][$id] = [
289
                'key_encryption_algorithms' => $jweDecrypter->getKeyEncryptionAlgorithmManager()->list(),
290
                'content_encryption_algorithms' => $jweDecrypter->getContentEncryptionAlgorithmManager()->list(),
291
                'compression_methods' => $jweDecrypter->getCompressionMethodManager()->list(),
292
                //Add header checkers
293
            ];
294
        }
295
    }
296
297
    private function collectJWK()
298
    {
299
        $this->data['jwk'] = [];
300
        foreach ($this->jwks as $id => $jwk) {
301
            $this->data['jwk'][$id] = [
302
                'jwk' => $jwk,
303
                'analyze' => $this->jwkAnalyzerManager === null ? [] : $this->jwkAnalyzerManager->analyze($jwk),
304
            ];
305
        }
306
    }
307
308
    private function collectJWKSet()
309
    {
310
        $this->data['jwkset'] = [];
311
        foreach ($this->jwksets as $id => $jwkset) {
312
            $analyze = [];
313
            if ($this->jwkAnalyzerManager !== null) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
314
            } else {
315
                foreach ($jwkset as $kid => $jwk) {
316
                    $analyze[$kid] = $this->jwkAnalyzerManager->analyze($jwk);
0 ignored issues
show
Bug introduced by
The method analyze cannot be called on $this->jwkAnalyzerManager (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
317
                }
318
            }
319
            $this->data['jwkset'][$id] = [
320
                'jwkset' => $jwkset,
321
                'analyze' => $analyze,
322
            ];
323
        }
324
    }
325
326
    /**
327
     * @var JWSBuilder[]
328
     */
329
    private $jwsBuilders = [];
330
331
    /**
332
     * @param string     $id
333
     * @param JWSBuilder $jwsBuilder
334
     */
335
    public function addJWSBuilder(string $id, JWSBuilder $jwsBuilder)
336
    {
337
        $this->jwsBuilders[$id] = $jwsBuilder;
338
    }
339
340
    /**
341
     * @var JWSVerifier[]
342
     */
343
    private $jwsVerifiers = [];
344
345
    /**
346
     * @param string      $id
347
     * @param JWSVerifier $jwsVerifier
348
     */
349
    public function addJWSVerifier(string $id, JWSVerifier $jwsVerifier)
350
    {
351
        $this->jwsVerifiers[$id] = $jwsVerifier;
352
    }
353
354
    /**
355
     * @var JWEBuilder[]
356
     */
357
    private $jweBuilders = [];
358
359
    /**
360
     * @param string     $id
361
     * @param JWEBuilder $jweBuilder
362
     */
363
    public function addJWEBuilder(string $id, JWEBuilder $jweBuilder)
364
    {
365
        $this->jweBuilders[$id] = $jweBuilder;
366
    }
367
368
    /**
369
     * @var JWEDecrypter[]
370
     */
371
    private $jweDecrypters = [];
372
373
    /**
374
     * @param string       $id
375
     * @param JWEDecrypter $jweDecrypter
376
     */
377
    public function addJWEDecrypter(string $id, JWEDecrypter $jweDecrypter)
378
    {
379
        $this->jweDecrypters[$id] = $jweDecrypter;
380
    }
381
382
    /**
383
     * @var JWK[]
384
     */
385
    private $jwks = [];
386
387
    /**
388
     * @param string $id
389
     * @param JWK    $jwk
390
     */
391
    public function addJWK(string $id, JWK $jwk)
392
    {
393
        $this->jwks[$id] = $jwk;
394
    }
395
396
    /**
397
     * @var JWKSet[]
398
     */
399
    private $jwksets = [];
400
401
    /**
402
     * @param string $id
403
     * @param JWKSet $jwkset
404
     */
405
    public function addJWKSet(string $id, JWKSet $jwkset)
406
    {
407
        $this->jwksets[$id] = $jwkset;
408
    }
409
}
410