Completed
Push — master ( 8b6623...b6ba4a )
by Florent
08:35
created

EasyJWTLoaderSource::createService()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 3
rs 10
cc 1
eloc 1
nc 1
nop 3
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\Source;
13
14
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
15
use Symfony\Component\DependencyInjection\ContainerBuilder;
16
17
final class EasyJWTLoaderSource implements SourceInterface
18
{
19
    /**
20
     * {@inheritdoc}
21
     */
22
    public function getName()
23
    {
24
        return 'easy_jwt_loader';
25
    }
26
27
    /**
28
     * {@inheritdoc}
29
     */
30
    public function createService($name, array $config, ContainerBuilder $container)
31
    {
32
    }
33
34
    /**
35
     * {@inheritdoc}
36
     */
37
    public function getNodeDefinition(ArrayNodeDefinition $node)
38
    {
39
        $node
40
            ->children()
41
                ->arrayNode('easy_jwt_loader')
42
                    ->useAttributeAsKey('name')
43
                    ->prototype('array')
44
                        ->children()
45
                            ->arrayNode('signature_algorithms')
46
                                ->useAttributeAsKey('name')
47
                                ->isRequired()
48
                                ->cannotBeEmpty()
49
                                ->prototype('scalar')->end()
50
                            ->end()
51
                            ->arrayNode('key_encryption_algorithms')
52
                                ->useAttributeAsKey('name')
53
                                ->defaultValue([])
54
                                ->prototype('scalar')->end()
55
                            ->end()
56
                            ->arrayNode('content_encryption_algorithms')
57
                                ->useAttributeAsKey('name')
58
                                ->defaultValue([])
59
                                ->prototype('scalar')->end()
60
                            ->end()
61
                            ->arrayNode('compression_methods')
62
                                ->useAttributeAsKey('name')
63
                                ->defaultValue(['DEF'])
64
                                ->prototype('scalar')->end()
65
                            ->end()
66
                            ->arrayNode('claim_checkers')
67
                                ->useAttributeAsKey('name')
68
                                ->defaultValue([])
69
                                ->prototype('scalar')->end()
70
                            ->end()
71
                            ->arrayNode('header_checkers')
72
                                ->useAttributeAsKey('name')
73
                                ->defaultValue([])
74
                                ->prototype('scalar')->end()
75
                            ->end()
76
                            ->scalarNode('logger')->defaultNull()->end()
77
                        ->end()
78
                    ->end()
79
                ->end()
80
            ->end();
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function prepend(ContainerBuilder $container, array $config)
87
    {
88
        if (false === array_key_exists($this->getName(), $config)) {
89
            return;
90
        }
91
92
        foreach ($config[$this->getName()] as $id => $section) {
93
            $config = $this->createServiceConfiguration($config, $id, $section);
94
        }
95
96
        return $config;
97
    }
98
99
    /**
100
     * @param array  $config
101
     * @param string $id
102
     * @param array  $section
103
     *
104
     * @return array
105
     */
106
    private function createServiceConfiguration(array $config, $id, array $section)
107
    {
108
        $config = $this->createVerifierServiceConfiguration($config, $id, $section);
109
        $config = $this->createDecrypterServiceConfiguration($config, $id, $section);
110
        $config = $this->createJWTLoaderServiceConfiguration($config, $id, $section);
111
        $config = $this->createCheckerServiceConfiguration($config, $id, $section);
112
113
        return $config;
114
    }
115
116
    /**
117
     * @param array  $config
118
     * @param string $id
119
     * @param array  $section
120
     *
121
     * @return array
122
     */
123
    private function createVerifierServiceConfiguration(array $config, $id, array $section)
124
    {
125
        $config['verifiers'] = array_merge(
126
            array_key_exists('verifiers', $config) ? $config['verifiers'] : [],
127
            [$id => [
128
                'algorithms' => $section['signature_algorithms'],
129
                'logger'     => array_key_exists('logger', $section) ? $section['logger'] : null,
130
            ]]
131
        );
132
133
        return $config;
134
    }
135
136
    /**
137
     * @param array  $config
138
     * @param string $id
139
     * @param array  $section
140
     *
141
     * @return array
142
     */
143
    private function createDecrypterServiceConfiguration(array $config, $id, array $section)
144
    {
145
        if (false === $this->isEncryptionSupportEnabled($section)) {
146
            return $config;
147
        }
148
        $config['decrypters'] = array_merge(
149
            array_key_exists('decrypters', $config) ? $config['decrypters'] : [],
150
            [$id => [
151
                'key_encryption_algorithms'     => $section['key_encryption_algorithms'],
152
                'content_encryption_algorithms' => $section['content_encryption_algorithms'],
153
                'compression_methods'           => $section['compression_methods'],
154
                'logger'                        => array_key_exists('logger', $section) ? $section['logger'] : null,
155
            ]]
156
        );
157
158
        return $config;
159
    }
160
161
    /**
162
     * @param array  $config
163
     * @param string $id
164
     * @param array  $section
165
     *
166
     * @return array
167
     */
168
    private function createCheckerServiceConfiguration(array $config, $id, array $section)
169
    {
170
        $config['checkers'] = array_merge(
171
            array_key_exists('checkers', $config) ? $config['checkers'] : [],
172
            [$id => [
173
                'claims'  => $section['claim_checkers'],
174
                'headers' => $section['header_checkers'],
175
            ]]
176
        );
177
178
        return $config;
179
    }
180
181
    /**
182
     * @param array  $config
183
     * @param string $id
184
     * @param array  $section
185
     *
186
     * @return array
187
     */
188
    private function createJWTLoaderServiceConfiguration(array $config, $id, array $section)
189
    {
190
        $service = [
191
            'verifier' => sprintf('jose.verifier.%s', $id),
192
            'checker'  => sprintf('jose.checker.%s', $id),
193
        ];
194
        if (true === $this->isEncryptionSupportEnabled($section)) {
195
            $service['decrypter'] = sprintf('jose.decrypter.%s', $id);
196
        }
197
        $config['jwt_loaders'] = array_merge(
198
            array_key_exists('jwt_loaders', $config) ? $config['jwt_loaders'] : [],
199
            [$id => $service]
200
        );
201
202
        return $config;
203
    }
204
205
    /**
206
     * @param array $section
207
     *
208
     * @return bool
209
     */
210
    private function isEncryptionSupportEnabled(array $section)
211
    {
212
        if (true === empty($section['key_encryption_algorithms']) && true === empty($section['content_encryption_algorithms'])) {
213
            return false;
214
        }
215
216
        if (true === empty($section['key_encryption_algorithms']) || true === empty($section['content_encryption_algorithms'])) {
217
            throw new \LogicException('Both key encryption algorithms and content encryption algorithms must be set to enable the encryption support.');
218
        }
219
220
        return true;
221
    }
222
}
223