GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Configuration::getConfigTreeBuilder()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 13
nc 1
nop 0
dl 0
loc 19
rs 9.8333
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Damax\Bundle\ApiAuthBundle\DependencyInjection;
6
7
use Damax\Bundle\ApiAuthBundle\Security\JsonResponseFactory;
8
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
9
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
10
use Symfony\Component\Config\Definition\ConfigurationInterface;
11
12
final class Configuration implements ConfigurationInterface
13
{
14
    public const SIGNER_SYMMETRIC = 'symmetric';
15
    public const SIGNER_ASYMMETRIC = 'asymmetric';
16
17
    private const SYMMETRIC_ALGOS = ['HS256', 'HS384', 'HS512'];
18
    private const ASYMMETRIC_ALGOS = ['RS256', 'RS384', 'RS512', 'ES256', 'ES384', 'ES512'];
19
20
    public const STORAGE_FIXED = 'fixed';
21
    public const STORAGE_REDIS = 'redis';
22
    public const STORAGE_DOCTRINE = 'doctrine';
23
24
    public function getConfigTreeBuilder(): TreeBuilder
25
    {
26
        $treeBuilder = new TreeBuilder();
27
28
        /** @var ArrayNodeDefinition $rootNode */
29
        $rootNode = $treeBuilder->root('damax_api_auth');
30
        $rootNode
31
            ->addDefaultsIfNotSet()
32
            ->children()
33
                ->scalarNode('response_factory_service_id')
34
                    ->cannotBeEmpty()
35
                    ->defaultValue(JsonResponseFactory::class)
36
                ->end()
37
                ->append($this->apiKeyNode('api_key'))
38
                ->append($this->jwtNode('jwt'))
39
            ->end()
40
        ;
41
42
        return $treeBuilder;
43
    }
44
45
    private function apiKeyNode(string $name): ArrayNodeDefinition
46
    {
47
        return (new ArrayNodeDefinition($name))
48
            ->canBeEnabled()
49
            ->children()
50
                ->append($this->extractorsNode('extractors', [
51
                    [
52
                        'type' => 'header',
53
                        'name' => 'Authorization',
54
                        'prefix' => 'Token',
55
                    ],
56
                ]))
57
58
                ->arrayNode('generator')
59
                    ->addDefaultsIfNotSet()
60
                    ->children()
61
                        ->integerNode('key_size')
62
                            ->defaultValue(20)
63
                        ->end()
64
                    ->end()
65
                ->end()
66
67
                ->arrayNode('storage')
68
                    ->beforeNormalization()
69
                        ->ifTrue(function (array $config): bool {
70
                            return !isset($config[0]);
71
                        })
72
                        ->then(function (array $config): array {
73
                            return [
74
                                ['type' => self::STORAGE_FIXED, 'tokens' => $config],
75
                            ];
76
                        })
77
                    ->end()
78
                    ->arrayPrototype()
79
                        ->children()
80
                            ->enumNode('type')
81
                                ->isRequired()
82
                                ->values([self::STORAGE_FIXED, self::STORAGE_REDIS, self::STORAGE_DOCTRINE])
83
                            ->end()
84
                            ->arrayNode('tokens')
85
                                ->useAttributeAsKey(true)
86
                                ->requiresAtLeastOneElement()
87
                                ->scalarPrototype()
88
                                    ->isRequired()
89
                                ->end()
90
                            ->end()
91
                            ->booleanNode('writable')
92
                                ->defaultFalse()
93
                            ->end()
94
                            ->scalarNode('redis_client_id')
95
                                ->cannotBeEmpty()
96
                                ->defaultValue('snc_redis.default')
97
                            ->end()
98
                            ->scalarNode('key_prefix')
99
                                ->cannotBeEmpty()
100
                            ->end()
101
                            ->scalarNode('doctrine_connection_id')
102
                                ->cannotBeEmpty()
103
                                ->defaultValue('database_connection')
104
                            ->end()
105
                            ->scalarNode('table_name')
106
                                ->cannotBeEmpty()
107
                                ->defaultValue('api_key')
108
                            ->end()
109
                            ->arrayNode('fields')
110
                                ->children()
111
                                    ->scalarNode('key')->cannotBeEmpty()->end()
112
                                    ->scalarNode('ttl')->cannotBeEmpty()->end()
113
                                    ->scalarNode('identity')->cannotBeEmpty()->end()
114
                                ->end()
115
                            ->end()
116
                        ->end()
117
                    ->end()
118
                ->end()
119
            ->end()
120
        ;
121
    }
122
123
    private function jwtNode(string $name): ArrayNodeDefinition
124
    {
125
        return (new ArrayNodeDefinition($name))
126
            ->beforeNormalization()
127
                ->ifString()
128
                ->then(function (string $config): array {
129
                    return ['signer' => $config];
130
                })
131
            ->end()
132
            ->canBeEnabled()
133
            ->children()
134
                ->append($this->extractorsNode('extractors', [
135
                    [
136
                        'type' => 'header',
137
                        'name' => 'Authorization',
138
                        'prefix' => 'Bearer',
139
                    ],
140
                ]))
141
                ->scalarNode('identity_claim')
142
                    ->cannotBeEmpty()
143
                ->end()
144
                ->arrayNode('builder')
145
                    ->addDefaultsIfNotSet()
146
                    ->children()
147
                        ->scalarNode('issuer')
148
                            ->cannotBeEmpty()
149
                        ->end()
150
                        ->scalarNode('audience')
151
                            ->cannotBeEmpty()
152
                        ->end()
153
                        ->integerNode('ttl')
154
                            ->defaultValue(3600)
155
                        ->end()
156
                    ->end()
157
                ->end()
158
                ->arrayNode('parser')
159
                    ->children()
160
                        ->arrayNode('issuers')
161
                            ->requiresAtLeastOneElement()
162
                            ->scalarPrototype()
163
                                ->isRequired()
164
                            ->end()
165
                        ->end()
166
                        ->scalarNode('audience')
167
                            ->cannotBeEmpty()
168
                        ->end()
169
                    ->end()
170
                ->end()
171
                ->arrayNode('signer')
172
                    ->isRequired()
173
                    ->beforeNormalization()
174
                        ->ifString()
175
                        ->then(function (string $config): array {
176
                            return ['signing_key' => $config];
177
                        })
178
                    ->end()
179
                    ->beforeNormalization()
180
                        ->ifTrue(function (?array $config): bool {
181
                            $type = $config['type'] ?? self::SIGNER_SYMMETRIC;
182
183
                            return self::SIGNER_ASYMMETRIC === $type;
184
                        })
185
                        ->then(function (array $config): array {
186
                            if (isset($config['signing_key'])) {
187
                                $config['signing_key'] = 'file://' . $config['signing_key'];
188
                            }
189
190
                            if (isset($config['verification_key'])) {
191
                                $config['verification_key'] = 'file://' . $config['verification_key'];
192
                            }
193
194
                            if (!isset($config['algorithm'])) {
195
                                $config['algorithm'] = self::ASYMMETRIC_ALGOS[0];
196
                            }
197
198
                            return $config;
199
                        })
200
                    ->end()
201
                    ->validate()
202
                        ->ifTrue(function (array $config): bool {
203
                            return self::SIGNER_ASYMMETRIC === $config['type'] && empty($config['verification_key']);
204
                        })
205
                        ->thenInvalid('Verification key must be specified for "asymmetric" signer.')
206
                    ->end()
207
                    ->validate()
208
                        ->ifTrue(function (array $config): bool {
209
                            return self::SIGNER_SYMMETRIC === $config['type'] && !in_array($config['algorithm'], self::SYMMETRIC_ALGOS);
210
                        })
211
                        ->thenInvalid('HMAC algorithm must be specified for "symmetric" signer.')
212
                    ->end()
213
                    ->validate()
214
                        ->ifTrue(function (array $config): bool {
215
                            return self::SIGNER_ASYMMETRIC === $config['type'] && !in_array($config['algorithm'], self::ASYMMETRIC_ALGOS);
216
                        })
217
                        ->thenInvalid('RSA or ECDSA algorithm must be specified for "asymmetric" signer.')
218
                    ->end()
219
                    ->validate()
220
                        ->ifTrue(function (array $config): bool {
221
                            if (self::SIGNER_SYMMETRIC === $config['type']) {
222
                                return false;
223
                            }
224
225
                            return !is_readable($config['signing_key']) || !is_readable($config['verification_key']);
226
                        })
227
                        ->thenInvalid('Signing and/or verification key is not readable.')
228
                    ->end()
229
                    ->validate()
230
                        ->ifTrue(function (array $config): bool {
231
                            return self::SIGNER_SYMMETRIC === $config['type'] && !empty($config['verification_key']);
232
                        })
233
                        ->thenInvalid('Verification key must no be specified for "symmetric" signer.')
234
                    ->end()
235
                    ->validate()
236
                        ->ifTrue(function (array $config): bool {
237
                            return self::SIGNER_SYMMETRIC === $config['type'] && !empty($config['passphrase']);
238
                        })
239
                        ->thenInvalid('Passphrase must not be specified for "symmetric" signer.')
240
                    ->end()
241
                    ->children()
242
                        ->enumNode('type')
243
                            ->values(['symmetric', 'asymmetric'])
244
                            ->defaultValue('symmetric')
245
                        ->end()
246
                        ->enumNode('algorithm')
247
                            ->values(array_merge(self::SYMMETRIC_ALGOS, self::ASYMMETRIC_ALGOS))
248
                            ->defaultValue(self::SYMMETRIC_ALGOS[0])
249
                        ->end()
250
                        ->scalarNode('signing_key')
251
                            ->isRequired()
252
                        ->end()
253
                        ->scalarNode('verification_key')
254
                            ->cannotBeEmpty()
255
                        ->end()
256
                        ->scalarNode('passphrase')
257
                            ->cannotBeEmpty()
258
                            ->defaultValue('')
259
                        ->end()
260
                    ->end()
261
                ->end()
262
            ->end()
263
        ;
264
    }
265
266
    private function extractorsNode(string $name, array $defaults): ArrayNodeDefinition
267
    {
268
        return (new ArrayNodeDefinition($name))
269
            ->arrayPrototype()
270
                ->children()
271
                    ->enumNode('type')
272
                        ->isRequired()
273
                        ->values(['header', 'query', 'cookie'])
274
                    ->end()
275
                    ->scalarNode('name')
276
                        ->isRequired()
277
                    ->end()
278
                    ->scalarNode('prefix')
279
                        ->cannotBeEmpty()
280
                    ->end()
281
                ->end()
282
            ->end()
283
            ->defaultValue($defaults)
284
        ;
285
    }
286
}
287