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   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 272
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 218
dl 0
loc 272
rs 10
c 0
b 0
f 0
wmc 14

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getConfigTreeBuilder() 0 19 1
A extractorsNode() 0 18 1
B apiKeyNode() 0 75 1
C jwtNode() 0 140 11
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