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\StepupBundle\DependencyInjection; |
20
|
|
|
|
21
|
|
|
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; |
22
|
|
|
use Symfony\Component\Config\Definition\Builder\TreeBuilder; |
23
|
|
|
use Symfony\Component\Config\Definition\ConfigurationInterface; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @codeCoverageIgnore |
27
|
|
|
*/ |
28
|
|
|
class Configuration implements ConfigurationInterface |
29
|
|
|
{ |
30
|
|
|
const DEFAULT_SMS_SERVICE = 'surfnet_stepup.service.gateway_api_sms'; |
31
|
|
|
|
32
|
|
|
public function getConfigTreeBuilder() |
33
|
|
|
{ |
34
|
|
|
$treeBuilder = new TreeBuilder; |
35
|
|
|
|
36
|
|
|
$rootNode = $treeBuilder->root('surfnet_bundle'); |
|
|
|
|
37
|
|
|
$rootNode |
38
|
|
|
->children() |
39
|
|
|
->arrayNode('logging') |
40
|
|
|
->isRequired() |
41
|
|
|
->children() |
42
|
|
|
->scalarNode('application_name') |
43
|
|
|
->info('This is the application name that is included with each log message') |
44
|
|
|
->isRequired() |
45
|
|
|
->validate() |
46
|
|
|
->ifTrue(function ($name) { |
47
|
|
|
return !is_string($name); |
48
|
|
|
}) |
49
|
|
|
->thenInvalid('surfnet_bundle.logging.application_name must be string') |
50
|
|
|
->end() |
51
|
|
|
->end() |
52
|
|
|
->end() |
53
|
|
|
->end() |
54
|
|
|
->arrayNode('loa_definition') |
55
|
|
|
->canBeDisabled() |
56
|
|
|
->children() |
57
|
|
|
->scalarNode('loa1') |
58
|
|
|
->example('https://gateway.tld/authentication/loa1') |
59
|
|
|
->validate() |
60
|
|
|
->ifTrue(function ($value) { |
61
|
|
|
return !is_string($value); |
62
|
|
|
}) |
63
|
|
|
->thenInvalid('Loa definition for "loa1" must be a string') |
64
|
|
|
->end() |
65
|
|
|
->end() |
66
|
|
|
->scalarNode('loa2') |
67
|
|
|
->example('https://gateway.tld/authentication/loa2') |
68
|
|
|
->validate() |
69
|
|
|
->ifTrue(function ($value) { |
70
|
|
|
return !is_string($value); |
71
|
|
|
}) |
72
|
|
|
->thenInvalid('Loa definition for "loa2" must be a string') |
73
|
|
|
->end() |
74
|
|
|
->end() |
75
|
|
|
->scalarNode('loa3') |
76
|
|
|
->example('https://gateway.tld/authentication/loa3') |
77
|
|
|
->validate() |
78
|
|
|
->ifTrue(function ($value) { |
79
|
|
|
return !is_string($value); |
80
|
|
|
}) |
81
|
|
|
->thenInvalid('Loa definition for "loa3" must be a string') |
82
|
|
|
->end() |
83
|
|
|
->end() |
84
|
|
|
->end() |
85
|
|
|
->end() |
86
|
|
|
->arrayNode('attach_request_id_injector_to') |
87
|
|
|
->prototype('scalar') |
88
|
|
|
->validate() |
89
|
|
|
->ifTrue(function ($serviceId) { return !is_string($serviceId); }) |
90
|
|
|
->thenInvalid('surfnet_bundle.attach_request_id_injector_to must be array of strings') |
91
|
|
|
->end() |
92
|
|
|
->end() |
93
|
|
|
->end(); |
94
|
|
|
|
95
|
|
|
$this->createGatewayApiConfiguration($rootNode); |
96
|
|
|
$this->createSmsConfiguration($rootNode); |
97
|
|
|
$this->createLocaleCookieConfiguration($rootNode); |
98
|
|
|
|
99
|
|
|
return $treeBuilder; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
private function createGatewayApiConfiguration(ArrayNodeDefinition $root) |
103
|
|
|
{ |
104
|
|
|
$root |
105
|
|
|
->children() |
106
|
|
|
->arrayNode('gateway_api') |
107
|
|
|
->canBeEnabled() |
108
|
|
|
->info('Gateway API configuration') |
109
|
|
|
->children() |
110
|
|
|
->arrayNode('credentials') |
111
|
|
|
->info('Basic authentication credentials') |
112
|
|
|
->children() |
113
|
|
|
->scalarNode('username') |
114
|
|
|
->info('Username for the Gateway API') |
115
|
|
|
->isRequired() |
116
|
|
|
->validate() |
117
|
|
|
->ifTrue(function ($value) { |
118
|
|
|
return (!is_string($value) || empty($value)); |
119
|
|
|
}) |
120
|
|
|
->thenInvalid( |
121
|
|
|
'Invalid Gateway API username specified: "%s". Must be non-empty string' |
122
|
|
|
) |
123
|
|
|
->end() |
124
|
|
|
->end() |
125
|
|
|
->scalarNode('password') |
126
|
|
|
->info('Password for the Gateway API') |
127
|
|
|
->isRequired() |
128
|
|
|
->validate() |
129
|
|
|
->ifTrue(function ($value) { |
130
|
|
|
return (!is_string($value) || empty($value)); |
131
|
|
|
}) |
132
|
|
|
->thenInvalid( |
133
|
|
|
'Invalid Gateway API password specified: "%s". Must be non-empty string' |
134
|
|
|
) |
135
|
|
|
->end() |
136
|
|
|
->end() |
137
|
|
|
->end() |
138
|
|
|
->end() |
139
|
|
|
->scalarNode('url') |
140
|
|
|
->info('The URL to the Gateway application (e.g. https://gateway.tld)') |
141
|
|
|
->isRequired() |
142
|
|
|
->validate() |
143
|
|
|
->ifTrue(function ($value) { |
144
|
|
|
return (!is_string($value) || empty($value) || !preg_match('~/$~', $value)); |
145
|
|
|
}) |
146
|
|
|
->thenInvalid( |
147
|
|
|
'Invalid Gateway URL specified: "%s". Must be string ending in forward slash' |
148
|
|
|
) |
149
|
|
|
->end() |
150
|
|
|
->end() |
151
|
|
|
->end() |
152
|
|
|
->end() |
153
|
|
|
->end(); |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
private function createSmsConfiguration(ArrayNodeDefinition $root) |
157
|
|
|
{ |
158
|
|
|
$root |
159
|
|
|
->children() |
160
|
|
|
->arrayNode('sms') |
161
|
|
|
->canBeDisabled() |
162
|
|
|
->info('SMS configuration') |
163
|
|
|
->isRequired() |
164
|
|
|
->children() |
165
|
|
|
->scalarNode('service') |
166
|
|
|
->info( |
167
|
|
|
'The ID of the SMS service used for sending SMS messages. ' . |
168
|
|
|
'Must implement "Surfnet\StepupBundle\Service\SmsService".' |
169
|
|
|
) |
170
|
|
|
->defaultValue(self::DEFAULT_SMS_SERVICE) |
171
|
|
|
->validate() |
172
|
|
|
->ifTrue(function ($value) { |
173
|
|
|
return !is_string($value); |
174
|
|
|
}) |
175
|
|
|
->thenInvalid('The SMS service ID must be specified using a string.') |
176
|
|
|
->end() |
177
|
|
|
->end() |
178
|
|
|
->scalarNode('originator') |
179
|
|
|
->info('Originator (sender) for SMS messages') |
180
|
|
|
->validate() |
181
|
|
|
->ifTrue(function ($value) { |
182
|
|
|
return (!is_string($value) || !preg_match('~^[a-z0-9]{1,11}$~i', $value)); |
183
|
|
|
}) |
184
|
|
|
->thenInvalid( |
185
|
|
|
'Invalid SMS originator specified: "%s". Must be a string matching ' |
186
|
|
|
. '"~^[a-z0-9]{1,11}$~i".' |
187
|
|
|
) |
188
|
|
|
->end() |
189
|
|
|
->end() |
190
|
|
|
->integerNode('otp_expiry_interval') |
191
|
|
|
->info('After how many seconds an SMS challenge OTP expires') |
192
|
|
|
->validate() |
193
|
|
|
->ifTrue(function ($value) { |
194
|
|
|
return $value <= 0; |
195
|
|
|
}) |
196
|
|
|
->thenInvalid( |
197
|
|
|
'Invalid SMS challenge OTP expiry, must be one or more seconds.' |
198
|
|
|
) |
199
|
|
|
->end() |
200
|
|
|
->end() |
201
|
|
|
->integerNode('maximum_otp_requests') |
202
|
|
|
->info('How many challenges a user may request during a session') |
203
|
|
|
->validate() |
204
|
|
|
->ifTrue(function ($value) { |
205
|
|
|
return $value <= 0; |
206
|
|
|
}) |
207
|
|
|
->thenInvalid( |
208
|
|
|
'Maximum OTP requests has a minimum of 1' |
209
|
|
|
) |
210
|
|
|
->end() |
211
|
|
|
->end() |
212
|
|
|
->end() |
213
|
|
|
->end() |
214
|
|
|
->end(); |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
private function createLocaleCookieConfiguration(ArrayNodeDefinition $root) |
218
|
|
|
{ |
219
|
|
|
$root |
220
|
|
|
->children() |
221
|
|
|
->arrayNode('locale_cookie') |
222
|
|
|
->canBeDisabled() |
223
|
|
|
->info('Cookie settings for locale cookie') |
224
|
|
|
->children() |
225
|
|
|
->scalarNode('name') |
226
|
|
|
->info('Name for the cookie') |
227
|
|
|
->defaultValue('stepup_locale') |
228
|
|
|
->end() |
229
|
|
|
->scalarNode('domain') |
230
|
|
|
->info('Domain the cookie is scoped to') |
231
|
|
|
->defaultValue('example.org') |
232
|
|
|
->end() |
233
|
|
|
->integerNode('expire') |
234
|
|
|
->info('Defines a specific number of seconds for when the browser should delete the cookie.') |
235
|
|
|
->defaultValue(0) |
236
|
|
|
->end() |
237
|
|
|
->scalarNode('path') |
238
|
|
|
->info('Path the cookie is scoped to') |
239
|
|
|
->defaultValue('/') |
240
|
|
|
->end() |
241
|
|
|
->booleanNode('secure') |
242
|
|
|
->info('Only transmit cookie over secure connections?') |
243
|
|
|
->defaultValue(true) |
244
|
|
|
->end() |
245
|
|
|
->booleanNode('http_only') |
246
|
|
|
->info('Directs browsers not to expose cookies through channels other than HTTP (and HTTPS) requests') |
247
|
|
|
->defaultValue(true) |
248
|
|
|
->end() |
249
|
|
|
->end() |
250
|
|
|
->end() |
251
|
|
|
->end(); |
252
|
|
|
} |
253
|
|
|
} |
254
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.