Passed
Push — master ( 9f2d68...309122 )
by Gerard
17:41
created

GbereSimpleAuthExtension::addProvidersSection()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 6
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 8
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gbere\SimpleAuth\DependencyInjection;
6
7
use Exception;
8
use Gbere\SimpleAuth\Security\LoginFormAuthenticator;
9
use Symfony\Component\Config\FileLocator;
10
use Symfony\Component\DependencyInjection\ContainerBuilder;
11
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
12
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
13
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
14
15
class GbereSimpleAuthExtension extends Extension implements PrependExtensionInterface
16
{
17
    private const TESTING_ROUTES = [
18
        ['path' => '^/gbere-auth-test-role-admin', 'role' => 'ROLE_ADMIN'],
19
        ['path' => '^/gbere-auth-test-role-user', 'role' => 'ROLE_USER'],
20
    ];
21
    private const SECURITY_PROVIDER_NAME = 'gbere_auth_main_provider';
22
    private const SECURITY_FIREWALL_NAME = 'gbere_auth_main_firewall';
23
24
    /** @var array|null */
25
    private $securityConfig;
26
    /** @var array|null */
27
    private $prependConfig;
28
29
    /**
30
     * @throws Exception
31
     */
32
    public function load(array $configs, ContainerBuilder $container): void
33
    {
34
        $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
35
        $loader->load('services.yaml');
36
37
        $configuration = $this->getConfiguration($configs, $container);
38
        $config = $this->processConfiguration($configuration, $configs);
0 ignored issues
show
Bug introduced by
It seems like $configuration can also be of type null; however, parameter $configuration of Symfony\Component\Depend...:processConfiguration() does only seem to accept Symfony\Component\Config...\ConfigurationInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

38
        $config = $this->processConfiguration(/** @scrutinizer ignore-type */ $configuration, $configs);
Loading history...
Unused Code introduced by
The assignment to $config is dead and can be removed.
Loading history...
39
    }
40
41
    public function prepend(ContainerBuilder $container): void
42
    {
43
        if ('test' === $container->getParameter('kernel.environment')) {
44
            $this->securityConfig['access_control'] = self::TESTING_ROUTES;
45
        }
46
47
        $this->prependConfig = $container->getExtensionConfig($this->getAlias());
48
        $this->addEncodersSection();
49
        $this->addProvidersSection();
50
        $this->addFirewallSection();
51
        $this->updateSecurityConfig($container);
52
    }
53
54
    private function addEncodersSection(): void
55
    {
56
        if (isset($this->prependConfig[0]['user'])) {
57
            $this->securityConfig['encoders'] = [
58
                $this->prependConfig[0]['user']['entity'] => [
59
                    'algorithm' => $this->prependConfig[0]['user']['encoder_algorithm'],
60
                ],
61
                // TODO:
62
                'Gbere\SimpleAuth\Entity\AdminUser' => [
63
                    'algorithm' => 'auto',
64
                ],
65
            ];
66
        }
67
    }
68
69
    private function addProvidersSection(): void
70
    {
71
        if (isset($this->prependConfig[0]['user'])) {
72
            $this->securityConfig['providers'] = [
73
                self::SECURITY_PROVIDER_NAME => [
74
                    'entity' => [
75
                        'class' => $this->prependConfig[0]['user']['entity'],
76
                        'property' => 'email',
77
                    ],
78
                ],
79
            ];
80
        }
81
    }
82
83
    private function addFirewallSection(): void
84
    {
85
        $this->securityConfig['firewalls'] = [
86
            self::SECURITY_FIREWALL_NAME => [
87
                'anonymous' => 'lazy',
88
                'provider' => self::SECURITY_PROVIDER_NAME,
89
                'guard' => [
90
                    'authenticators' => [LoginFormAuthenticator::class],
91
                ],
92
                'logout' => [
93
                    'path' => 'gbere_auth_logout',
94
                ],
95
            ],
96
        ];
97
98
        if (isset($this->prependConfig[0]['remember_me_lifetime']) && null != $this->prependConfig[0]['remember_me_lifetime']) {
99
            $this->securityConfig['firewalls'][self::SECURITY_FIREWALL_NAME]['remember_me'] = [
100
                'secret' => '%kernel.secret%',
101
                'lifetime' => $this->prependConfig[0]['remember_me_lifetime'],
102
            ];
103
        }
104
    }
105
106
    private function updateSecurityConfig(ContainerBuilder $container): void
107
    {
108
        if (null === $this->securityConfig) {
109
            return;
110
        }
111
112
        $extensionConfigsRefl = new \ReflectionProperty(ContainerBuilder::class, 'extensionConfigs');
113
        $extensionConfigsRefl->setAccessible(true);
114
        $extensionConfigs = $extensionConfigsRefl->getValue($container);
115
116
        foreach ($this->securityConfig as $section => $configs) {
117
            if (isset($extensionConfigs['security'][0][$section])) {
118
                // gbere_auth_main_firewall must be inserted after the firewall->dev
119
                if ('firewalls' === $section) {
120
                    $extensionConfigs['security'][0][$section] = array_merge($extensionConfigs['security'][0][$section], $configs);
121
                } else {
122
                    $extensionConfigs['security'][0][$section] = array_merge($configs, $extensionConfigs['security'][0][$section]);
123
                }
124
            } else {
125
                $extensionConfigs['security'][0][$section] = $configs;
126
            }
127
        }
128
129
        $extensionConfigsRefl->setValue($container, $extensionConfigs);
130
    }
131
}
132