Completed
Push — develop ( 64a224...17d645 )
by Florent
03:11
created

SpomkyLabsJoseBundleExtension   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 313
Duplicated Lines 47.92 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 24
Bugs 8 Features 5
Metric Value
wmc 38
c 24
b 8
f 5
lcom 1
cbo 10
dl 150
loc 313
rs 8.3999

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A load() 0 17 2
A getConfiguration() 0 7 1
A getAlias() 0 4 1
D initConfiguration() 0 30 8
A createJWKSet() 12 12 3
A createJWK() 12 12 3
A createEncrypter() 20 20 3
A createDecrypter() 16 16 2
A createSigner() 19 19 3
A createVerifier() 15 15 2
A createChecker() 16 16 2
A getXmlFileToLoad() 0 13 1
A createJWKSources() 20 20 3
A createJWKSetSources() 20 20 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2014-2016 Spomky-Labs
7
 *
8
 * This software may be modified and distributed under the terms
9
 * of the MIT license.  See the LICENSE file for details.
10
 */
11
12
namespace SpomkyLabs\JoseBundle\DependencyInjection;
13
14
use Symfony\Component\Config\Definition\Processor;
15
use Symfony\Component\Config\FileLocator;
16
use Symfony\Component\DependencyInjection\ContainerBuilder;
17
use Symfony\Component\DependencyInjection\Definition;
18
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
19
use Symfony\Component\DependencyInjection\Reference;
20
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
21
22
final class SpomkyLabsJoseBundleExtension extends Extension
23
{
24
    /**
25
     * @var \SpomkyLabs\JoseBundle\DependencyInjection\JWKSource\JWKSourceInterface[]
26
     */
27
    private $jwk_sources;
28
29
    /**
30
     * @var \SpomkyLabs\JoseBundle\DependencyInjection\JWKSetSource\JWKSetSourceInterface[]
31
     */
32
    private $jwk_set_sources;
33
34
    /**
35
     * @var string
36
     */
37
    private $alias;
38
39
    /**
40
     * @param string $alias
41
     */
42
    public function __construct($alias)
43
    {
44
        $this->alias = $alias;
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50
    public function load(array $configs, ContainerBuilder $container)
51
    {
52
        $processor = new Processor();
53
54
        $config = $processor->processConfiguration(
55
            $this->getConfiguration($configs, $container),
56
            $configs
57
        );
58
59
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
60
        $services = $this->getXmlFileToLoad();
61
        foreach ($services as $basename) {
62
            $loader->load(sprintf('%s.xml', $basename));
63
        }
64
65
        $this->initConfiguration($container, $config);
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71
    public function getConfiguration(array $configs, ContainerBuilder $container)
72
    {
73
        $jwk_sources = $this->createJWKSources();
74
        $jwk_set_sources = $this->createJWKSetSources();
75
76
        return new Configuration($this->getAlias(), $jwk_sources, $jwk_set_sources);
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82
    public function getAlias()
83
    {
84
        return $this->alias;
85
    }
86
87
    /**
88
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
89
     * @param array                                                   $config
90
     */
91
    private function initConfiguration(ContainerBuilder $container, array $config)
92
    {
93
        foreach ($config['keys'] as $name => $key) {
94
            $this->createJWK($name, $key, $container, $this->jwk_sources);
95
        }
96
97
        foreach ($config['key_sets'] as $name => $key_set) {
98
            $this->createJWKSet($name, $key_set, $container, $this->jwk_set_sources);
99
        }
100
101
        foreach ($config['encrypters'] as $name => $encrypter) {
102
            $this->createEncrypter($name, $encrypter, $container);
103
        }
104
105
        foreach ($config['decrypters'] as $name => $decrypter) {
106
            $this->createDecrypter($name, $decrypter, $container);
107
        }
108
109
        foreach ($config['signers'] as $name => $signer) {
110
            $this->createSigner($name, $signer, $container);
111
        }
112
113
        foreach ($config['verifiers'] as $name => $verifier) {
114
            $this->createVerifier($name, $verifier, $container);
115
        }
116
117
        foreach ($config['checkers'] as $name => $checker) {
118
            $this->createChecker($name, $checker, $container);
119
        }
120
    }
121
122
    /**
123
     * @param string                                                                       $name
124
     * @param array                                                                        $config
125
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder                      $container
126
     * @param \SpomkyLabs\JoseBundle\DependencyInjection\JWKSetSource\JWKSetSourceInterface[] $jwk_set_sources
127
     */
128 View Code Duplication
    private function createJWKSet($name, array $config, ContainerBuilder $container, array $jwk_set_sources)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
129
    {
130
        foreach ($config as $key => $adapter) {
131
            if (array_key_exists($key, $jwk_set_sources)) {
132
                $service_id = sprintf('jose.key_set.%s', $name);
133
                $jwk_set_sources[$key]->create($container, $service_id, $adapter);
134
135
                return;
136
            }
137
        }
138
        throw new \LogicException(sprintf('The JWKSet definition "%s" is not configured.', $name));
139
    }
140
141
    /**
142
     * @param string                                                                    $name
143
     * @param array                                                                     $config
144
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder                   $container
145
     * @param \SpomkyLabs\JoseBundle\DependencyInjection\JWKSource\JWKSourceInterface[] $jwk_sources
146
     */
147 View Code Duplication
    private function createJWK($name, array $config, ContainerBuilder $container, array $jwk_sources)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
148
    {
149
        foreach ($config as $key => $adapter) {
150
            if (array_key_exists($key, $jwk_sources)) {
151
                $service_id = sprintf('jose.key.%s', $name);
152
                $jwk_sources[$key]->create($container, $service_id, $adapter);
153
154
                return;
155
            }
156
        }
157
        throw new \LogicException(sprintf('The JWK definition "%s" is not configured.', $name));
158
    }
159
160
    /**
161
     * @param string                                                  $name
162
     * @param array                                                   $config
163
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
164
     */
165 View Code Duplication
    private function createEncrypter($name, array $config, ContainerBuilder $container)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
166
    {
167
        $service_id = sprintf('jose.encrypter.%s', $name);
168
        $definition = new Definition('Jose\Encrypter');
169
        $definition->setFactory([
170
            new Reference('jose.factory.service'),
171
            'createEncrypter',
172
        ]);
173
        $definition->setArguments([
174
            $config['algorithms'],
175
            $config['compression_methods'],
176
            null === $config['logger'] ? null : new Reference($config['logger']),
177
        ]);
178
179
        $container->setDefinition($service_id, $definition);
180
        
181
        if (true === $config['create_decrypter']) {
182
            $this->createDecrypter($name, $config, $container);
183
        }
184
    }
185
186
    /**
187
     * @param string                                                  $name
188
     * @param array                                                   $config
189
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
190
     */
191 View Code Duplication
    private function createDecrypter($name, array $config, ContainerBuilder $container)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
192
    {
193
        $service_id = sprintf('jose.decrypter.%s', $name);
194
        $definition = new Definition('Jose\Decrypter');
195
        $definition->setFactory([
196
            new Reference('jose.factory.service'),
197
            'createDecrypter',
198
        ]);
199
        $definition->setArguments([
200
            $config['algorithms'],
201
            $config['compression_methods'],
202
            null === $config['logger'] ? null : new Reference($config['logger']),
203
        ]);
204
        
205
        $container->setDefinition($service_id, $definition);
206
    }
207
208
    /**
209
     * @param string                                                  $name
210
     * @param array                                                   $config
211
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
212
     */
213 View Code Duplication
    private function createSigner($name, array $config, ContainerBuilder $container)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
214
    {
215
        $service_id = sprintf('jose.signer.%s', $name);
216
        $definition = new Definition('Jose\Signer');
217
        $definition->setFactory([
218
            new Reference('jose.factory.service'),
219
            'createSigner',
220
        ]);
221
        $definition->setArguments([
222
            $config['algorithms'],
223
            null === $config['logger'] ? null : new Reference($config['logger']),
224
        ]);
225
226
        $container->setDefinition($service_id, $definition);
227
        
228
        if (true === $config['create_verifier']) {
229
            $this->createVerifier($name, $config, $container);
230
        }
231
    }
232
233
    /**
234
     * @param string                                                  $name
235
     * @param array                                                   $config
236
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
237
     */
238 View Code Duplication
    private function createVerifier($name, array $config, ContainerBuilder $container)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
239
    {
240
        $service_id = sprintf('jose.verifier.%s', $name);
241
        $definition = new Definition('Jose\Verifier');
242
        $definition->setFactory([
243
            new Reference('jose.factory.service'),
244
            'createVerifier',
245
        ]);
246
        $definition->setArguments([
247
            $config['algorithms'],
248
            null === $config['logger'] ? null : new Reference($config['logger']),
249
        ]);
250
        
251
        $container->setDefinition($service_id, $definition);
252
    }
253
254
    /**
255
     * @param string                                                  $name
256
     * @param array                                                   $config
257
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
258
     */
259 View Code Duplication
    private function createChecker($name, array $config, ContainerBuilder $container)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
260
    {
261
        $service_id = sprintf('jose.checker.%s', $name);
262
        $definition = new Definition('Jose\Checker\CheckerManager');
263
        $definition->setFactory([
264
            new Reference('jose.factory.service'),
265
            'createChecker',
266
        ]);
267
        $definition->setArguments([
268
            $config['claims'],
269
            $config['headers'],
270
            null === $config['logger'] ? null : new Reference($config['logger']),
271
        ]);
272
273
        $container->setDefinition($service_id, $definition);
274
    }
275
276
    /**
277
     * @return string[]
278
     */
279
    private function getXmlFileToLoad()
280
    {
281
        $services = [
282
            'services',
283
            'compression_methods',
284
            'checkers',
285
            'signature_algorithms',
286
            'encryption_algorithms',
287
            'checkers',
288
        ];
289
290
        return $services;
291
    }
292
293 View Code Duplication
    private function createJWKSources()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
294
    {
295
        if (null !== $this->jwk_sources) {
296
            return $this->jwk_sources;
297
        }
298
299
        // load bundled adapter factories
300
        $tempContainer = new ContainerBuilder();
301
        $loader = new XmlFileLoader($tempContainer, new FileLocator(__DIR__.'/../Resources/config'));
302
        $loader->load('jwk_sources.xml');
303
304
        $services = $tempContainer->findTaggedServiceIds('jose.jwk_source');
305
        $jwk_sources = [];
306
        foreach (array_keys($services) as $id) {
307
            $factory = $tempContainer->get($id);
308
            $jwk_sources[str_replace('-', '_', $factory->getKey())] = $factory;
309
        }
310
311
        return $this->jwk_sources = $jwk_sources;
312
    }
313
314 View Code Duplication
    private function createJWKSetSources()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
315
    {
316
        if (null !== $this->jwk_set_sources) {
317
            return $this->jwk_set_sources;
318
        }
319
320
        // load bundled adapter factories
321
        $tempContainer = new ContainerBuilder();
322
        $loader = new XmlFileLoader($tempContainer, new FileLocator(__DIR__.'/../Resources/config'));
323
        $loader->load('jwk_set_sources.xml');
324
325
        $services = $tempContainer->findTaggedServiceIds('jose.jwk_set_source');
326
        $jwk_set_sources = [];
327
        foreach (array_keys($services) as $id) {
328
            $factory = $tempContainer->get($id);
329
            $jwk_set_sources[str_replace('-', '_', $factory->getKeySet())] = $factory;
330
        }
331
332
        return $this->jwk_set_sources = $jwk_set_sources;
333
    }
334
}
335