Completed
Branch master (910c19)
by Dmitri
01:43
created

ConfigurationTest::it_processes_simplified_api_key_config()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
nc 1
nop 0
dl 0
loc 27
rs 9.7
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Damax\Bundle\ApiAuthBundle\Tests\DependencyInjection;
6
7
use Damax\Bundle\ApiAuthBundle\DependencyInjection\Configuration;
8
use Damax\Bundle\ApiAuthBundle\Security\JsonResponseFactory;
9
use Matthias\SymfonyConfigTest\PhpUnit\ConfigurationTestCaseTrait;
10
use PHPUnit\Framework\TestCase;
11
use Symfony\Component\Config\Definition\ConfigurationInterface;
12
13
class ConfigurationTest extends TestCase
14
{
15
    use ConfigurationTestCaseTrait;
16
17
    /**
18
     * @test
19
     */
20
    public function it_processes_empty_config()
21
    {
22
        $config = [];
23
24
        $this->assertProcessedConfigurationEquals([$config], [
25
            'api_key' => [
26
                'enabled' => false,
27
                'extractors' => [
28
                    ['type' => 'header', 'name' => 'Authorization', 'prefix' => 'Token'],
29
                ],
30
                'generator' => ['key_size' => 20],
31
                'storage' => [],
32
            ],
33
            'jwt' => [
34
                'enabled' => false,
35
                'extractors' => [
36
                    ['type' => 'header', 'name' => 'Authorization', 'prefix' => 'Bearer'],
37
                ],
38
                'builder' => [
39
                    'ttl' => 3600,
40
                ],
41
            ],
42
            'response_factory_service_id' => JsonResponseFactory::class,
43
        ]);
44
    }
45
46
    /**
47
     * @test
48
     */
49
    public function it_configures_response_factory()
50
    {
51
        $config = [
52
            'response_factory_service_id' => 'factory_service_id',
53
        ];
54
55
        $this->assertProcessedConfigurationEquals([$config], [
56
            'response_factory_service_id' => 'factory_service_id',
57
        ], 'response_factory_service_id');
58
    }
59
60
    /**
61
     * @test
62
     */
63
    public function it_processes_simplified_api_key_config()
64
    {
65
        $config = [
66
            'api_key' => [
67
                'storage' => ['foo' => 'bar', 'baz' => 'qux'],
68
            ],
69
        ];
70
71
        $this->assertProcessedConfigurationEquals([$config], [
72
            'api_key' => [
73
                'enabled' => true,
74
                'extractors' => [
75
                    ['type' => 'header', 'name' => 'Authorization', 'prefix' => 'Token'],
76
                ],
77
                'generator' => ['key_size' => 20],
78
                'storage' => [
79
                    [
80
                        'type' => 'fixed',
81
                        'tokens' => ['foo' => 'bar', 'baz' => 'qux'],
82
                        'writable' => false,
83
                        'table_name' => 'api_key',
84
                        'redis_client_id' => 'snc_redis.default',
85
                        'doctrine_connection_id' => 'database_connection',
86
                    ],
87
                ],
88
            ],
89
        ], 'api_key');
90
    }
91
92
    /**
93
     * @test
94
     */
95
    public function it_configures_api_key()
96
    {
97
        $config = [
98
            'api_key' => [
99
                'extractors' => [
100
                    ['type' => 'header', 'name' => 'Authorization', 'prefix' => 'Token'],
101
                    ['type' => 'query', 'name' => 'api_key'],
102
                    ['type' => 'cookie', 'name' => 'api_key'],
103
                ],
104
                'generator' => ['key_size' => 40],
105
                'storage' => [
106
                    [
107
                        'type' => 'fixed',
108
                        'tokens' => ['foo' => 'bar', 'baz' => 'qux'],
109
                    ],
110
                    [
111
                        'type' => 'redis',
112
                        'writable' => true,
113
                        'redis_client_id' => 'redis_service_id',
114
                        'key_prefix' => 'api_',
115
                    ],
116
                    [
117
                        'type' => 'doctrine',
118
                        'writable' => false,
119
                        'doctrine_connection_id' => 'doctrine_connection',
120
                        'table_name' => 'keys',
121
                        'fields' => ['key' => 'id', 'identity' => 'email', 'ttl' => 'expires_at'],
122
                    ],
123
                ],
124
            ],
125
        ];
126
127
        $this->assertProcessedConfigurationEquals([$config], [
128
            'api_key' => [
129
                'enabled' => true,
130
                'extractors' => [
131
                    ['type' => 'header', 'name' => 'Authorization', 'prefix' => 'Token'],
132
                    ['type' => 'query', 'name' => 'api_key'],
133
                    ['type' => 'cookie', 'name' => 'api_key'],
134
                ],
135
                'generator' => ['key_size' => 40],
136
                'storage' => [
137
                    [
138
                        'type' => 'fixed',
139
                        'tokens' => ['foo' => 'bar', 'baz' => 'qux'],
140
                        'writable' => false,
141
                        'redis_client_id' => 'snc_redis.default',
142
                        'doctrine_connection_id' => 'database_connection',
143
                        'table_name' => 'api_key',
144
                    ],
145
                    [
146
                        'type' => 'redis',
147
                        'tokens' => [],
148
                        'writable' => true,
149
                        'redis_client_id' => 'redis_service_id',
150
                        'key_prefix' => 'api_',
151
                        'doctrine_connection_id' => 'database_connection',
152
                        'table_name' => 'api_key',
153
                    ],
154
                    [
155
                        'type' => 'doctrine',
156
                        'tokens' => [],
157
                        'writable' => false,
158
                        'redis_client_id' => 'snc_redis.default',
159
                        'doctrine_connection_id' => 'doctrine_connection',
160
                        'table_name' => 'keys',
161
                        'fields' => ['key' => 'id', 'identity' => 'email', 'ttl' => 'expires_at'],
162
                    ],
163
                ],
164
            ],
165
        ], 'api_key');
166
    }
167
168
    /**
169
     * @test
170
     */
171
    public function it_requires_verification_key_for_asymmetric_signer()
172
    {
173
        $config = [
174
            'jwt' => [
175
                'signer' => [
176
                    'type' => 'asymmetric',
177
                    'signing_key' => 'secret',
178
                ],
179
            ],
180
        ];
181
182
        $this->assertPartialConfigurationIsInvalid([$config], 'jwt', 'Verification key must be specified for "asymmetric" signer.');
183
    }
184
185
    /**
186
     * @test
187
     */
188
    public function it_requires_hmac_algorithm_for_symmetric_signer()
189
    {
190
        $config = [
191
            'jwt' => [
192
                'signer' => [
193
                    'type' => 'symmetric',
194
                    'algorithm' => 'RS256',
195
                    'signing_key' => 'secret',
196
                ],
197
            ],
198
        ];
199
200
        $this->assertPartialConfigurationIsInvalid([$config], 'jwt', 'HMAC algorithm must be specified for "symmetric" signer.');
201
    }
202
203
    /**
204
     * @test
205
     */
206
    public function it_requires_rsa_algorithm_for_asymmetric_signer()
207
    {
208
        $config = [
209
            'jwt' => [
210
                'signer' => [
211
                    'type' => 'asymmetric',
212
                    'algorithm' => 'HS256',
213
                    'signing_key' => 'signing_secret',
214
                    'verification_key' => 'verification_secret',
215
                ],
216
            ],
217
        ];
218
219
        $this->assertPartialConfigurationIsInvalid([$config], 'jwt', 'RSA or ECDSA algorithm must be specified for "asymmetric" signer.');
220
    }
221
222
    /**
223
     * @test
224
     */
225
    public function it_requires_readable_signing_and_verification_key()
226
    {
227
        $config = [
228
            'jwt' => [
229
                'signer' => [
230
                    'type' => 'asymmetric',
231
                    'algorithm' => 'RS256',
232
                    'signing_key' => 'signing_secret',
233
                    'verification_key' => 'verification_secret',
234
                ],
235
            ],
236
        ];
237
238
        $this->assertPartialConfigurationIsInvalid([$config], 'jwt', 'Signing and/or verification key is not readable.');
239
    }
240
241
    /**
242
     * @test
243
     */
244
    public function it_requires_no_verification_key_for_symmetric_signer()
245
    {
246
        $config = [
247
            'jwt' => [
248
                'signer' => [
249
                    'signing_key' => 'signing_secret',
250
                    'verification_key' => 'verification_secret',
251
                ],
252
            ],
253
        ];
254
255
        $this->assertPartialConfigurationIsInvalid([$config], 'jwt', 'Verification key must no be specified for "symmetric" signer.');
256
    }
257
258
    /**
259
     * @test
260
     */
261
    public function it_requires_no_passphrase_for_symmetric_signer()
262
    {
263
        $config = [
264
            'jwt' => [
265
                'signer' => [
266
                    'signing_key' => 'signing_secret',
267
                    'passphrase' => '__XYZ__',
268
                ],
269
            ],
270
        ];
271
272
        $this->assertPartialConfigurationIsInvalid([$config], 'jwt', 'Passphrase must not be specified for "symmetric" signer.');
273
    }
274
275
    /**
276
     * @test
277
     */
278
    public function it_processes_simplified_jwt_config()
279
    {
280
        $config = [
281
            'jwt' => 'secret',
282
        ];
283
284
        $this->assertProcessedConfigurationEquals([$config], [
285
            'jwt' => [
286
                'enabled' => true,
287
                'builder' => [
288
                    'ttl' => 3600,
289
                ],
290
                'extractors' => [
291
                    ['type' => 'header', 'name' => 'Authorization', 'prefix' => 'Bearer'],
292
                ],
293
                'signer' => [
294
                    'type' => 'symmetric',
295
                    'algorithm' => 'HS256',
296
                    'signing_key' => 'secret',
297
                    'passphrase' => '',
298
                ],
299
            ],
300
        ], 'jwt');
301
    }
302
303
    /**
304
     * @test
305
     */
306
    public function it_configures_jwt()
307
    {
308
        $filename = tempnam(sys_get_temp_dir(), 'key_');
309
310
        $config = [
311
            'jwt' => [
312
                'builder' => [
313
                    'issuer' => 'damax-api-auth-bundle',
314
                    'audience' => 'symfony',
315
                    'ttl' => 600,
316
                ],
317
                'parser' => [
318
                    'issuers' => ['symfony', 'zend'],
319
                    'audience' => 'zend',
320
                ],
321
                'extractors' => [
322
                    ['type' => 'header', 'name' => 'Authorization', 'prefix' => 'Bearer'],
323
                    ['type' => 'query', 'name' => 'token'],
324
                    ['type' => 'cookie', 'name' => 'token'],
325
                ],
326
                'signer' => [
327
                    'type' => 'asymmetric',
328
                    'signing_key' => $filename,
329
                    'verification_key' => $filename,
330
                ],
331
            ],
332
        ];
333
334
        $this->assertProcessedConfigurationEquals([$config], [
335
            'jwt' => [
336
                'enabled' => true,
337
                'builder' => [
338
                    'issuer' => 'damax-api-auth-bundle',
339
                    'audience' => 'symfony',
340
                    'ttl' => 600,
341
                ],
342
                'parser' => [
343
                    'issuers' => ['symfony', 'zend'],
344
                    'audience' => 'zend',
345
                ],
346
                'extractors' => [
347
                    ['type' => 'header', 'name' => 'Authorization', 'prefix' => 'Bearer'],
348
                    ['type' => 'query', 'name' => 'token'],
349
                    ['type' => 'cookie', 'name' => 'token'],
350
                ],
351
                'signer' => [
352
                    'type' => 'asymmetric',
353
                    'algorithm' => 'RS256',
354
                    'signing_key' => 'file://' . $filename,
355
                    'verification_key' => 'file://' . $filename,
356
                    'passphrase' => '',
357
                ],
358
            ],
359
        ], 'jwt');
360
361
        unlink($filename);
362
    }
363
364
    protected function getConfiguration(): ConfigurationInterface
365
    {
366
        return new Configuration();
367
    }
368
}
369