TreeHouseKeystoneExtension::replaceLegacyTokenAuthenticator()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 9.4286
cc 3
eloc 4
nc 2
nop 1
crap 3
1
<?php
2
3
namespace TreeHouse\KeystoneBundle\DependencyInjection;
4
5
use Symfony\Component\Config\FileLocator;
6
use Symfony\Component\DependencyInjection\ContainerBuilder;
7
use Symfony\Component\DependencyInjection\Definition;
8
use Symfony\Component\DependencyInjection\DefinitionDecorator;
9
use Symfony\Component\DependencyInjection\Loader;
10
use Symfony\Component\DependencyInjection\Reference;
11
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
12
use Symfony\Component\HttpKernel\Kernel;
13
use TreeHouse\KeystoneBundle\Security\Authentication\LegacyTokenAuthenticator;
14
15
class TreeHouseKeystoneExtension extends Extension
16
{
17
    /**
18
     * @inheritdoc
19
     */
20 12
    public function load(array $configs, ContainerBuilder $container)
21
    {
22 12
        $configuration = new Configuration();
23 12
        $config = $this->processConfiguration($configuration, $configs);
24
25 12
        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
26 12
        $loader->load('services.yml');
27 12
        $loader->load('security.yml');
28
29 12
        $container->setParameter('tree_house.keystone.model.user.class', $config['user_class']);
30 12
        $container->setParameter('tree_house.keystone.user_provider.id', $config['user_provider_id']);
31 12
        $container->setParameter('tree_house.keystone.service_types', $config['service_types']);
32
33 12
        $userProviderServiceId = $container->getParameter('tree_house.keystone.user_provider.id');
34 12
        $container->setAlias('tree_house.keystone.user_provider', $userProviderServiceId);
35
36 12
        $this->loadServices($container, $config['services'], $config['service_types']);
37 8
        $this->replaceLegacyTokenAuthenticator($container);
38 8
    }
39
40
    /**
41
     * @param ContainerBuilder $container
42
     * @param array            $services
43
     * @param array            $types
44
     *
45
     * @throws \LogicException
46
     */
47 12
    private function loadServices(ContainerBuilder $container, array $services, array $types)
48
    {
49 12
        $manager = $container->getDefinition('tree_house.keystone.service_manager');
50 12
        $manager->addMethodCall('setTypes', [$types]);
51
52 12
        foreach ($services as $name => $serviceConfig) {
53 12
            if (!in_array($serviceConfig['type'], $types)) {
54 2
                throw new \LogicException(
55 1
                    sprintf(
56 2
                        'Service must be one of the registered types (%s), "%s" given',
57 2
                        implode(', ', $types),
58 2
                        $serviceConfig['type']
59 1
                    )
60 1
                );
61
            }
62
63 10
            $grant = null;
64 10
            if (!empty($serviceConfig['role'])) {
65 6
                $grant = $serviceConfig['role'];
66 3
            }
67
68 10
            if (!empty($serviceConfig['expression'])) {
69 4
                if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
70
                    throw new \LogicException(
71
                        'Unable to use expressions as the Symfony ExpressionLanguage component is not installed.'
72
                    );
73
                }
74
75 4
                if (null !== $grant) {
76 2
                    throw new \LogicException(<<<EOT
77
You cannot set both a role and expression for a service.
78
If you want to know how you can use the expression language
79
to check for roles, consult the documentation:
80
81
http://symfony.com/doc/current/book/security.html#complex-access-controls-with-expressions
82
83
EOT
84 1
                    );
85
                }
86
87 2
                $grant = new Definition('Symfony\Component\ExpressionLanguage\Expression');
88 2
                $grant->setPublic(false);
89 2
                $grant->addArgument($serviceConfig['expression']);
90 1
            }
91
92 8
            $id = sprintf('tree_house.keystone.service.%s', $name);
93 8
            $service = $container->setDefinition($id, new DefinitionDecorator('tree_house.keystone.service'));
94 8
            $service->replaceArgument(0, $name);
95 8
            $service->replaceArgument(1, $serviceConfig['type']);
96 8
            $service->replaceArgument(2, $grant ?: 'ROLE_USER');
97
98 8
            foreach ($serviceConfig['endpoint'] as $endpointConfig) {
99 8
                $service->addMethodCall('addEndpoint', [$endpointConfig['public_url'], $endpointConfig['admin_url']]);
100 4
            }
101
102 8
            $manager->addMethodCall('addService', [new Reference($id)]);
103 4
        }
104 8
    }
105
106
    /**
107
     * Replaces token authenticator service with legacy class for older Symfony versions.
108
     *
109
     * @todo remove when Symfony 2.6 and 2.7 are no longer supported
110
     *
111
     * @param ContainerBuilder $container
112
     */
113 8
    private function replaceLegacyTokenAuthenticator(ContainerBuilder $container)
114
    {
115 8
        if ((int) Kernel::MAJOR_VERSION === 2 && Kernel::MINOR_VERSION < 8) {
116 4
            $definition = $container->getDefinition('tree_house.keystone.token_authenticator');
117 4
            $definition->setClass(LegacyTokenAuthenticator::class);
118 4
        }
119 8
    }
120
}
121