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 ( 69ad8e...5f5918 )
by Dmitri
02:42
created

DamaxApiAuthExtension::configureKeyStorage()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 9
nop 2
dl 0
loc 35
rs 8.7377
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\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\Request\RequestMatcher;
23
use Damax\Bundle\ApiAuthBundle\Security\ApiKey\Authenticator as ApiKeyAuthenticator;
24
use Damax\Bundle\ApiAuthBundle\Security\ApiKey\StorageUserProvider;
25
use Damax\Bundle\ApiAuthBundle\Security\Jwt\AuthenticationHandler;
26
use Damax\Bundle\ApiAuthBundle\Security\Jwt\Authenticator as JwtAuthenticator;
27
use Lcobucci\Clock\SystemClock;
28
use Lcobucci\JWT\Configuration as JwtConfiguration;
29
use Lcobucci\JWT\Signer\Key;
30
use Symfony\Component\Config\FileLocator;
31
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
32
use Symfony\Component\DependencyInjection\ContainerBuilder;
33
use Symfony\Component\DependencyInjection\Definition;
34
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
35
use Symfony\Component\DependencyInjection\Reference;
36
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
37
38
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
131
            ->register('damax.api_auth.jwt.handler', AuthenticationHandler::class)
132
            ->setAutowired(true)
133
        ;
134
135
        return $this;
136
    }
137
138
    private function configureExceptions(array $config, ContainerBuilder $container): self
139
    {
140
        $container
141
            ->register(ExceptionListener::class)
142
            ->setAutowired(true)
143
            ->addTag('kernel.event_listener', ['event' => 'kernel.exception', 'method' => 'onKernelException'])
144
            ->setArgument(1, new Definition(RequestMatcher::class, [$config['base_url']]))
145
        ;
146
147
        return $this;
148
    }
149
150
    private function configureJwtClaims(array $config, Definition $clock, ContainerBuilder $container): Definition
151
    {
152
        // Default claims.
153
        $container
154
            ->register(TimestampClaims::class)
155
            ->addArgument($clock)
156
            ->addArgument($config['ttl'])
157
            ->addTag('damax.api_auth.jwt_claims')
158
        ;
159
        $container
160
            ->register(OrganizationClaims::class)
161
            ->addArgument($config['issuer'] ?? null)
162
            ->addArgument($config['audience'] ?? null)
163
            ->addTag('damax.api_auth.jwt_claims')
164
        ;
165
        $container
166
            ->register(SecurityClaims::class)
167
            ->addTag('damax.api_auth.jwt_claims')
168
        ;
169
170
        $container->setAlias(Claims::class, ClaimsCollector::class);
171
172
        return $container
173
            ->register(ClaimsCollector::class)
174
            ->addArgument(new TaggedIteratorArgument('damax.api_auth.jwt_claims'))
175
        ;
176
    }
177
178
    private function configureJwtSigner(array $config): Definition
179
    {
180
        $dirs = ['HS' => 'Hmac', 'RS' => 'Rsa', 'ES' => 'Ecdsa'];
181
        $algo = $config['algorithm'];
182
183
        return new Definition('Lcobucci\\JWT\\Signer\\' . $dirs[substr($algo, 0, 2)] . '\\Sha' . substr($algo, 2));
184
    }
185
186
    private function configureExtractors(array $config): Definition
187
    {
188
        $extractors = [];
189
190
        foreach ($config as $item) {
191
            $className = sprintf('Damax\\Bundle\\ApiAuthBundle\\Extractor\\%sExtractor', ucfirst($item['type']));
192
193
            $extractors[] = (new Definition($className))
194
                ->setArgument(0, $item['name'])
195
                ->setArgument(1, $item['prefix'] ?? null)
196
            ;
197
        }
198
199
        return new Definition(ChainExtractor::class, [$extractors]);
200
    }
201
202
    private function configureKeyStorage(array $config, ContainerBuilder $container): self
203
    {
204
        $drivers = [];
205
206
        // Default writable storage.
207
        $container->register(Writer::class, DummyStorage::class);
208
209
        foreach ($config as $item) {
210
            $className = sprintf('Damax\\Bundle\\ApiAuthBundle\\Key\\Storage\\%sStorage', ucfirst($item['type']));
211
212
            $drivers[] = $driver = new Definition($className);
213
214
            if (Configuration::STORAGE_FIXED === $item['type']) {
215
                $driver->addArgument($item['tokens']);
216
            } elseif (Configuration::STORAGE_REDIS === $item['type']) {
217
                $driver->addArgument(new Reference($item['redis_client_id']));
218
            } elseif (Configuration::STORAGE_DOCTRINE === $item['type']) {
219
                $driver
220
                    ->addArgument(new Reference($item['doctrine_connection_id']))
221
                    ->addArgument($item['table_name'])
222
                    ->addArgument($item['fields'] ?? [])
223
                ;
224
            }
225
226
            if ($item['writable']) {
227
                $container->setDefinition(Writer::class, $driver);
228
            }
229
        }
230
231
        $container
232
            ->register(Reader::class, ChainStorage::class)
233
            ->addArgument($drivers)
234
        ;
235
236
        return $this;
237
    }
238
}
239