Completed
Push — release-2.x ( 027c1f...75a22f )
by
unknown
15s
created

loadProviderConfiguration()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 53
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 53
rs 9.5797
c 0
b 0
f 0
cc 2
eloc 39
nc 2
nop 4

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
/**
4
 * Copyright 2014 SURFnet bv
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace Surfnet\StepupSelfService\SamlStepupProviderBundle\DependencyInjection;
20
21
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
22
use Symfony\Component\Config\FileLocator;
23
use Symfony\Component\DependencyInjection\ContainerBuilder;
24
use Symfony\Component\DependencyInjection\Definition;
25
use Symfony\Component\DependencyInjection\Loader;
26
use Symfony\Component\DependencyInjection\Reference;
27
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
28
29
class SurfnetStepupSelfServiceSamlStepupProviderExtension extends Extension
30
{
31
    /**
32
     * {@inheritdoc}
33
     */
34
    public function load(array $configs, ContainerBuilder $container)
35
    {
36
        $configuration = new Configuration();
37
        $config = $this->processConfiguration($configuration, $configs);
38
        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
39
        $loader->load('services.yml');
40
41
        foreach ($config['providers'] as $provider => $providerConfiguration) {
42
            // may seem a bit strange, but this prevents casing issue when getting/setting/creating provider
43
            // service definitions etc.
44
            if ($provider !== strtolower($provider)) {
45
                throw new InvalidConfigurationException('The provider name must be completely lowercase');
46
            }
47
48
            $this->loadProviderConfiguration($provider, $providerConfiguration, $config['routes'], $container);
49
        }
50
    }
51
52
    private function loadProviderConfiguration(
53
        $provider,
54
        array $configuration,
55
        array $routes,
56
        ContainerBuilder $container
57
    ) {
58
59
        if ($container->has('gssp.provider.' . $provider)) {
60
            throw new InvalidConfigurationException(sprintf('Cannot create the same provider "%s" twice', $provider));
61
        }
62
63
        $this->createHostedDefinitions($provider, $configuration['hosted'], $routes, $container);
64
        $this->createMetadataDefinition($provider, $configuration['hosted'], $routes, $container);
65
        $this->createRemoteDefinition($provider, $configuration['remote'], $container);
66
67
        $stateHandlerDefinition = new Definition('Surfnet\StepupSelfService\SamlStepupProviderBundle\Saml\StateHandler', [
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 122 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
68
            new Reference('gssp.sessionbag'),
69
            $provider
70
        ]);
71
        $container->setDefinition('gssp.provider.' . $provider . '.statehandler', $stateHandlerDefinition);
72
73
        $providerDefinition = new Definition('Surfnet\StepupSelfService\SamlStepupProviderBundle\Provider\Provider', [
74
            $provider,
75
            new Reference('gssp.provider.' . $provider . '.hosted.sp'),
76
            new Reference('gssp.provider.' . $provider . '.remote.idp'),
77
            new Reference('gssp.provider.' . $provider . '.statehandler')
78
        ]);
79
80
        $providerDefinition->setPublic(false);
81
        $container->setDefinition('gssp.provider.' . $provider, $providerDefinition);
82
83
        $viewConfigDefinition = new Definition('Surfnet\StepupSelfService\SamlStepupProviderBundle\Provider\ViewConfig', [
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 122 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
84
            new Reference('request'),
85
            $configuration['view_config']['loa'],
86
            $configuration['view_config']['logo'],
87
            $configuration['view_config']['alt'],
88
            $configuration['view_config']['title'],
89
            $configuration['view_config']['description'],
90
            $configuration['view_config']['button_use'],
91
            $configuration['view_config']['initiate_title'],
92
            $configuration['view_config']['initiate_button'],
93
            $configuration['view_config']['explanation'],
94
            $configuration['view_config']['authn_failed'],
95
            $configuration['view_config']['pop_failed'],
96
        ]);
97
        $viewConfigDefinition->setScope('request');
98
99
        $container->setDefinition('gssp.view_config.' . $provider, $viewConfigDefinition);
100
101
        $container
102
            ->getDefinition('gssp.provider_repository')
103
            ->addMethodCall('addProvider', [new Reference('gssp.provider.' . $provider)]);
104
    }
105
106
    /**
107
     * @param string           $provider
108
     * @param array            $configuration
109
     * @param array            $routes
110
     * @param ContainerBuilder $container
111
     */
112
    private function createHostedDefinitions(
113
        $provider,
114
        array $configuration,
115
        array $routes,
116
        ContainerBuilder $container
117
    ) {
118
        $hostedDefinition = $this->buildHostedEntityDefinition($provider, $configuration, $routes);
119
        $container->setDefinition('gssp.provider.' . $provider . '.hosted_entities', $hostedDefinition);
120
121
        $hostedSpDefinition  = (new Definition())
122
            ->setClass('Surfnet\SamlBundle\Entity\ServiceProvider')
123
            ->setFactory([
124
                new Reference('gssp.provider.' . $provider . '.hosted_entities'),
125
                'getServiceProvider'
126
            ])
127
            ->setPublic(false);
128
        $container->setDefinition('gssp.provider.' . $provider . '.hosted.sp', $hostedSpDefinition);
129
    }
130
131
    /**
132
     * @param string $provider
133
     * @param array  $configuration
134
     * @param array  $routes
135
     * @return Definition
136
     */
137
    private function buildHostedEntityDefinition($provider, array $configuration, array $routes)
138
    {
139
        $entityId = ['entity_id_route' => $this->createRouteConfig($provider, $routes['metadata'])];
140
        $spAdditional = [
141
            'enabled' => true,
142
            'assertion_consumer_route' => $this->createRouteConfig($provider, $routes['consume_assertion'])
143
        ];
144
        $idpAdditional = [
145
            'enabled' => false,
146
        ];
147
148
        $serviceProvider  = array_merge($configuration['service_provider'], $spAdditional, $entityId);
149
        $identityProvider = array_merge($idpAdditional, $entityId);
150
151
        $hostedDefinition = new Definition('Surfnet\SamlBundle\Entity\HostedEntities', [
152
            new Reference('router'),
153
            new Reference('request_stack'),
154
            $serviceProvider,
155
            $identityProvider
156
        ]);
157
158
        $hostedDefinition->setPublic(false);
159
160
        return $hostedDefinition;
161
    }
162
163
    /**
164
     * @param string           $provider
165
     * @param array            $configuration
166
     * @param ContainerBuilder $container
167
     */
168
    private function createRemoteDefinition($provider, array $configuration, ContainerBuilder $container)
169
    {
170
        $definition    = new Definition('Surfnet\SamlBundle\Entity\IdentityProvider', [
171
            [
172
                'entityId'        => $configuration['entity_id'],
173
                'ssoUrl'          => $configuration['sso_url'],
174
                'certificateData' => $configuration['certificate'],
175
            ]
176
        ]);
177
178
        $definition->setPublic(false);
179
        $container->setDefinition('gssp.provider.' . $provider . '.remote.idp', $definition);
180
    }
181
182
    /**
183
     * @param string           $provider
184
     * @param array            $configuration
185
     * @param array            $routes
186
     * @param ContainerBuilder $container
187
     * @return Definition
0 ignored issues
show
Documentation introduced by
Should the return type not be Definition|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
188
     */
189
    private function createMetadataDefinition(
190
        $provider,
191
        array $configuration,
192
        array $routes,
193
        ContainerBuilder $container
194
    ) {
195
        $metadataConfiguration = new Definition('Surfnet\SamlBundle\Metadata\MetadataConfiguration');
196
197
        $propertyMap = [
198
            'entityIdRoute'          => $this->createRouteConfig($provider, $routes['metadata']),
199
            'isSp'                   => true,
200
            'assertionConsumerRoute' => $this->createRouteConfig($provider, $routes['consume_assertion']),
201
            'isIdP'                  => false,
202
            'publicKey'              => $configuration['metadata']['public_key'],
203
            'privateKey'             => $configuration['metadata']['private_key'],
204
        ];
205
206
        $metadataConfiguration->setProperties($propertyMap);
207
        $metadataConfiguration->setPublic(false);
208
        $container->setDefinition('gssp.provider.' . $provider . 'metadata.configuration', $metadataConfiguration);
209
210
        $metadataFactory = new Definition('Surfnet\SamlBundle\Metadata\MetadataFactory', [
211
            new Reference('templating'),
212
            new Reference('router'),
213
            new Reference('surfnet_saml.signing_service'),
214
            new Reference('gssp.provider.' . $provider . 'metadata.configuration')
215
        ]);
216
        $container->setDefinition('gssp.provider.' . $provider . '.metadata.factory', $metadataFactory);
217
    }
218
219
    private function createRouteConfig($provider, $routeName)
220
    {
221
        // In the future, we ought to wrap this in an object.
222
        // https://www.pivotaltracker.com/story/show/90095392
223
        return [
224
            'route'      => $routeName,
225
            'parameters' => ['provider' => $provider]
226
        ];
227
    }
228
}
229