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.
Completed
Push — master ( 4a72af...750ca9 )
by Dmitri
02:32
created

DamaxApiAuthExtension::configureJwt()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 2
dl 0
loc 53
rs 9.0254
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Damax\Bundle\ApiAuthBundle\DependencyInjection;
6
7
use Damax\Bundle\ApiAuthBundle\Extractor\ChainExtractor;
8
use Damax\Bundle\ApiAuthBundle\Jwt\Claims;
9
use Damax\Bundle\ApiAuthBundle\Jwt\Claims\ClaimsCollector;
10
use Damax\Bundle\ApiAuthBundle\Jwt\Claims\OrganizationClaims;
11
use Damax\Bundle\ApiAuthBundle\Jwt\Claims\SecurityClaims;
12
use Damax\Bundle\ApiAuthBundle\Jwt\Claims\TimestampClaims;
13
use Damax\Bundle\ApiAuthBundle\Jwt\Lcobucci\Builder;
14
use Damax\Bundle\ApiAuthBundle\Jwt\Lcobucci\Parser;
15
use Damax\Bundle\ApiAuthBundle\Jwt\TokenBuilder;
16
use Damax\Bundle\ApiAuthBundle\Key\Generator\Generator;
17
use Damax\Bundle\ApiAuthBundle\Key\Storage\ChainStorage;
18
use Damax\Bundle\ApiAuthBundle\Key\Storage\DummyStorage;
19
use Damax\Bundle\ApiAuthBundle\Key\Storage\Reader;
20
use Damax\Bundle\ApiAuthBundle\Key\Storage\Writer;
21
use Damax\Bundle\ApiAuthBundle\Listener\ExceptionListener;
22
use Damax\Bundle\ApiAuthBundle\Security\ApiKey\Authenticator as ApiKeyAuthenticator;
23
use Damax\Bundle\ApiAuthBundle\Security\ApiKey\StorageUserProvider;
24
use Damax\Bundle\ApiAuthBundle\Security\Jwt\AuthenticationHandler;
25
use Damax\Bundle\ApiAuthBundle\Security\Jwt\Authenticator as JwtAuthenticator;
26
use Lcobucci\Clock\SystemClock;
27
use Lcobucci\JWT\Configuration as JwtConfiguration;
28
use Lcobucci\JWT\Signer\Key;
29
use Symfony\Component\Config\FileLocator;
30
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
31
use Symfony\Component\DependencyInjection\ContainerBuilder;
32
use Symfony\Component\DependencyInjection\Definition;
33
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
34
use Symfony\Component\DependencyInjection\Reference;
35
use Symfony\Component\HttpFoundation\RequestMatcher;
36
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
37
38
final class DamaxApiAuthExtension extends ConfigurableExtension
39
{
40
    protected function loadInternal(array $config, ContainerBuilder $container)
41
    {
42
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
43
        $loader->load('services.xml');
44
45
        if ($config['api_key']['enabled']) {
46
            $this->configureApiKey($config['api_key'], $container);
47
        }
48
49
        if ($config['jwt']['enabled']) {
50
            $this->configureJwt($config['jwt'], $container);
51
        }
52
53
        if ($config['format_exceptions']['enabled']) {
54
            $this->configureExceptions($config['format_exceptions'], $container);
55
        }
56
    }
57
58
    private function configureApiKey(array $config, ContainerBuilder $container): self
59
    {
60
        $extractors = $this->configureExtractors($config['extractors']);
61
62
        // User provider.
63
        $container->autowire('damax.api_auth.api_key.user_provider', StorageUserProvider::class);
64
65
        // Authenticator.
66
        $container
67
            ->register('damax.api_auth.api_key.authenticator', ApiKeyAuthenticator::class)
68
            ->addArgument($extractors)
69
        ;
70
71
        // Key generator.
72
        $container
73
            ->register(Generator::class)
74
            ->setClass(sprintf('Damax\\Bundle\\ApiAuthBundle\\Key\\Generator\\%sGenerator', ucfirst($config['generator'])))
75
        ;
76
77
        return $this->configureKeyStorage($config['storage'], $container);
78
    }
79
80
    private function configureJwt(array $config, ContainerBuilder $container): self
81
    {
82
        $signer = $this->configureJwtSigner($config['signer']);
83
84
        $clock = new Definition(SystemClock::class);
85
86
        $configuration = (new Definition(JwtConfiguration::class))
87
            ->setFactory(JwtConfiguration::class . '::forSymmetricSigner')
88
            ->addArgument($signer)
89
            ->addArgument(new Definition(Key::class, [
90
                $config['signer']['signing_key'],
91
                $config['signer']['passphrase'],
92
            ]))
93
        ;
94
95
        if (Configuration::SIGNER_ASYMMETRIC === $config['signer']['type']) {
96
            $configuration
97
                ->setFactory(JwtConfiguration::class . '::forAsymmetricSigner')
98
                ->addArgument(new Definition(Key::class, [
99
                    $config['signer']['verification_key'],
100
                ]))
101
            ;
102
        }
103
104
        $parser = (new Definition(Parser::class))
105
            ->addArgument($configuration)
106
            ->addArgument($clock)
107
            ->addArgument($config['parser']['issuers'] ?? null)
108
            ->addArgument($config['parser']['audience'] ?? null)
109
        ;
110
111
        $claims = $this->configureJwtClaims($config['builder'], $clock, $container);
112
113
        $container
114
            ->register(TokenBuilder::class, Builder::class)
115
            ->addArgument($configuration)
116
            ->addArgument($claims)
117
        ;
118
119
        $extractors = $this->configureExtractors($config['extractors']);
120
121
        // Authenticator.
122
        $container
123
            ->register('damax.api_auth.jwt.authenticator', JwtAuthenticator::class)
124
            ->addArgument($extractors)
125
            ->addArgument($parser)
126
            ->addArgument($config['identity_claim'] ?? null)
127
        ;
128
129
        // Handler.
130
        $container->autowire('damax.api_auth.jwt.handler', AuthenticationHandler::class);
131
132
        return $this;
133
    }
134
135
    private function configureExceptions(array $config, ContainerBuilder $container): self
136
    {
137
        $matcher = (new Definition(RequestMatcher::class))->addArgument($config['path'] ?? null);
138
139
        $container
140
            ->autowire(ExceptionListener::class)
141
            ->setArgument(1, $matcher)
142
            ->addTag('kernel.event_listener', ['event' => 'kernel.exception', 'method' => 'onKernelException'])
143
        ;
144
145
        return $this;
146
    }
147
148
    private function configureJwtClaims(array $config, Definition $clock, ContainerBuilder $container): Definition
149
    {
150
        // Default claims.
151
        $container
152
            ->register(TimestampClaims::class)
153
            ->addArgument($clock)
154
            ->addArgument($config['ttl'])
155
            ->addTag('damax.api_auth.jwt_claims')
156
        ;
157
        $container
158
            ->register(OrganizationClaims::class)
159
            ->addArgument($config['issuer'] ?? null)
160
            ->addArgument($config['audience'] ?? null)
161
            ->addTag('damax.api_auth.jwt_claims')
162
        ;
163
        $container
164
            ->register(SecurityClaims::class)
165
            ->addTag('damax.api_auth.jwt_claims')
166
        ;
167
168
        $container->setAlias(Claims::class, ClaimsCollector::class);
169
170
        return $container
171
            ->register(ClaimsCollector::class)
172
            ->addArgument(new TaggedIteratorArgument('damax.api_auth.jwt_claims'))
173
        ;
174
    }
175
176
    private function configureJwtSigner(array $config): Definition
177
    {
178
        $dirs = ['HS' => 'Hmac', 'RS' => 'Rsa', 'ES' => 'Ecdsa'];
179
        $algo = $config['algorithm'];
180
181
        return new Definition('Lcobucci\\JWT\\Signer\\' . $dirs[substr($algo, 0, 2)] . '\\Sha' . substr($algo, 2));
182
    }
183
184
    private function configureExtractors(array $config): Definition
185
    {
186
        $extractors = [];
187
188
        foreach ($config as $item) {
189
            $className = sprintf('Damax\\Bundle\\ApiAuthBundle\\Extractor\\%sExtractor', ucfirst($item['type']));
190
191
            $extractors[] = (new Definition($className))
192
                ->setArgument(0, $item['name'])
193
                ->setArgument(1, $item['prefix'] ?? null)
194
            ;
195
        }
196
197
        return new Definition(ChainExtractor::class, [$extractors]);
198
    }
199
200
    private function configureKeyStorage(array $config, ContainerBuilder $container): self
201
    {
202
        $drivers = [];
203
204
        // Default writable storage.
205
        $container->register(Writer::class, DummyStorage::class);
206
207
        foreach ($config as $item) {
208
            $className = sprintf('Damax\\Bundle\\ApiAuthBundle\\Key\\Storage\\%sStorage', ucfirst($item['type']));
209
210
            $drivers[] = $driver = new Definition($className);
211
212
            if (Configuration::STORAGE_FIXED === $item['type']) {
213
                $driver->addArgument($item['tokens']);
214
            } elseif (Configuration::STORAGE_REDIS === $item['type']) {
215
                $driver->addArgument(new Reference($item['redis_client_id']));
216
            } elseif (Configuration::STORAGE_DOCTRINE === $item['type']) {
217
                $driver
218
                    ->addArgument(new Reference($item['doctrine_connection_id']))
219
                    ->addArgument($item['table_name'])
220
                    ->addArgument($item['fields'] ?? [])
221
                ;
222
            }
223
224
            if ($item['writable']) {
225
                $container->setDefinition(Writer::class, $driver);
226
            }
227
        }
228
229
        $container
230
            ->register(Reader::class, ChainStorage::class)
231
            ->addArgument($drivers)
232
        ;
233
234
        return $this;
235
    }
236
}
237