ShibbolethServiceProvider::getLogoutUrlAttribute()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Kuleuven\AuthenticationBundle\Service;
4
5
use Symfony\Component\HttpFoundation\Request;
6
use Symfony\Component\HttpFoundation\RequestStack;
7
8
class ShibbolethServiceProvider implements AttributesByUsernameProviderInterface
9
{
10
    /**
11
     * @var RequestStack
12
     */
13
    protected $requestStack;
14
15
    /**
16
     * @var AttributeDefinitionsProviderInterface
17
     */
18
    protected $attributeDefinitionsProvider;
19
20
    /**
21
     * @var bool
22
     */
23
    protected $securedHandler;
24
25
    /**
26
     * @var string
27
     */
28
    protected $handlerPath;
29
30
    /**
31
     * @var string
32
     */
33
    protected $statusPath;
34
35
    /**
36
     * @var string
37
     */
38
    protected $sessionLoginPath;
39
40
    /**
41
     * @var string
42
     */
43
    protected $sessionLogoutPath;
44
45
    /**
46
     * @var string
47
     */
48
    protected $sessionOverviewPath;
49
50
    /**
51
     * @var string
52
     */
53
    protected $usernameAttribute;
54
55
    /**
56
     * @var string
57
     */
58
    protected $authenticatedAttribute;
59
60
    /**
61
     * @var string
62
     */
63
    protected $logoutUrlAttribute;
64
65
    /**
66
     * @var array
67
     */
68
    protected $authenticationRequirements;
69
70
    /**
71
     * @var string
72
     */
73
    protected $defaultCharset;
74
75
    /**
76
     * @var Request
77
     */
78
    protected $request;
79
80
    /**
81
     * @var bool
82
     */
83
    protected $authenticated;
84
85
    /**
86
     * @param RequestStack                          $requestStack
87
     * @param AttributeDefinitionsProviderInterface $attributeDefinitionsProvider
88
     * @param bool                                  $securedHandler
89
     * @param string                                $handlerPath
90
     * @param string                                $statusPath
91
     * @param string                                $sessionLoginPath
92
     * @param string                                $sessionLogoutPath
93
     * @param string                                $sessionOverviewPath
94
     * @param string                                $usernameAttribute
95
     * @param string                                $authenticatedAttribute
96
     * @param string                                $logoutUrlAttribute
97
     * @param array                                 $authenticationRequirements
98
     * @param string                                $defaultCharset
99
     */
100
    public function __construct(
101
        RequestStack $requestStack,
102
        AttributeDefinitionsProviderInterface $attributeDefinitionsProvider,
103
        $securedHandler,
104
        $handlerPath,
105
        $statusPath,
106
        $sessionLoginPath,
107
        $sessionLogoutPath,
108
        $sessionOverviewPath,
109
        $usernameAttribute,
110
        $authenticatedAttribute,
111
        $logoutUrlAttribute,
112
        $authenticationRequirements,
113
        $defaultCharset
114
    )
115
    {
116
        $this->requestStack = $requestStack;
117
        $this->attributeDefinitionsProvider = $attributeDefinitionsProvider;
118
        $this->securedHandler = $securedHandler;
119
        $this->handlerPath = $handlerPath;
120
        $this->statusPath = $statusPath;
121
        $this->sessionLoginPath = $sessionLoginPath;
122
        $this->sessionLogoutPath = $sessionLogoutPath;
123
        $this->sessionOverviewPath = $sessionOverviewPath;
124
        $this->usernameAttribute = $usernameAttribute;
125
        $this->authenticatedAttribute = $authenticatedAttribute;
126
        $this->logoutUrlAttribute = $logoutUrlAttribute;
127
        $this->authenticationRequirements = $authenticationRequirements;
128
        $this->defaultCharset = $defaultCharset;
129
    }
130
131
    /**
132
     * @return bool
133
     */
134
    public function isSecuredHandler()
135
    {
136
        return $this->securedHandler;
137
    }
138
139
    /**
140
     * @return string
141
     */
142
    public function getHandlerPath()
143
    {
144
        return $this->handlerPath;
145
    }
146
147
    /**
148
     * @return string
149
     */
150
    public function getSessionLoginPath()
151
    {
152
        return $this->sessionLoginPath;
153
    }
154
155
    /**
156
     * @return string
157
     */
158
    public function getSessionLogoutPath()
159
    {
160
        return $this->sessionLogoutPath;
161
    }
162
163
    /**
164
     * @return string
165
     */
166
    public function getSessionOverviewPath()
167
    {
168
        return $this->sessionOverviewPath;
169
    }
170
171
    /**
172
     * @return string
173
     */
174
    public function getStatusPath()
175
    {
176
        return $this->statusPath;
177
    }
178
179
    /**
180
     * @return Request
181
     */
182
    protected function getRequest()
183
    {
184
        if (empty($this->request)) {
185
            $this->request = $this->requestStack->getCurrentRequest();
186
        }
187
188
        return $this->request;
189
    }
190
191
    /**
192
     * @param null $fallback
193
     * @return array
194
     */
195
    public function getAttributes($fallback = null)
196
    {
197
        $attributeDefinitions = $this->attributeDefinitionsProvider->getAttributeDefinitions();
198
        $attributes = [];
199
        foreach ($attributeDefinitions as $idOrAlias => $attributeDefinition) {
200
            $attributes[$idOrAlias] = $this->getAttribute($idOrAlias, $fallback);
201
        }
202
        return $attributes;
203
    }
204
205
    /**
206
     * @param string $name
207
     * @param null   $fallback
208
     * @return null|string
209
     */
210
    public function getAttribute($name, $fallback = null)
211
    {
212
        $request = $this->requestStack->getCurrentRequest();
213
        return $request->server->get($name, $fallback);
214
    }
215
216
    /**
217
     * @param string $name
218
     * @return bool
219
     */
220
    public function hasAttribute($name)
221
    {
222
        $empty = microtime(true);
223
        return $empty !== $this->getAttribute($name, $empty);
224
    }
225
226
    /**
227
     * @param array $keyValues
228
     * @return bool
229
     */
230
    public function hasAttributeValues(array $keyValues)
231
    {
232
        $result = true;
233
        $empty = microtime(true);
234
        set_error_handler(function ($errno, $errstr) {
235
            throw new \Exception($errstr, $errno);
236
        });
237
        foreach ($keyValues as $checkName => $checkValue) {
238
            $value = $this->getAttribute($checkName, $empty);
239
            if ($checkValue !== $value) {
240
                try {
241
                    $result = (1 === preg_match($checkValue, $value));
242
                } catch (\Exception $e) {
243
                    $result = false;
244
                }
245
            }
246
            if (!$result) {
247
                break;
248
            }
249
        }
250
        restore_error_handler();
251
        return $result;
252
    }
253
254
    /**
255
     * @return bool
256
     */
257
    public function isAuthenticated()
258
    {
259
        if (null === $this->authenticated) {
260
            $this->authenticated = $this->hasAttributeValues($this->getAuthenticationRequirements());
261
        }
262
263
        return $this->authenticated;
264
    }
265
266
    /**
267
     * @return string
268
     */
269
    public function getUsername()
270
    {
271
        return $this->getAttribute($this->usernameAttribute);
272
    }
273
274
    /**
275
     * @param $username
276
     * @return array
277
     */
278
    public function getAttributesByUsername($username)
279
    {
280
        if ($username !== $this->getUsername()) {
281
            return [];
282
        }
283
284
        return $this->getAttributes(null);
285
    }
286
287
    /**
288
     * Returns shibboleth session URL
289
     *
290
     * @return string
291
     */
292
    public function getHandlerUrl()
293
    {
294
        $request = $this->getRequest();
295
        return (($this->isSecuredHandler()) ? 'https://' : 'http://') . $request->getHost() . $this->getHandlerPath();
296
    }
297
298
    /**
299
     * Returns URL to initiate login session. After successful login, the user will be redirected
300
     * to the optional target page. The target can be an absolute or relative URL.
301
     *
302
     * @param string|null $target URL to redirect to after successful login. Defaults to the current request URL.
303
     * @return string The absolute URL to initiate a session
304
     */
305
    public function getLoginUrl($target = null)
306
    {
307
        $request = $this->getRequest();
308
        if (empty($target)) {
309
            $target = $request->getUri();
310
        }
311
        return $this->getHandlerUrl() . $this->getSessionLoginPath() . '?target=' . urlencode($target);
312
    }
313
314
    /**
315
     * Returns URL to invalidate the shibboleth session.
316
     *
317
     * @param null $target URL to redirect to after successful logout. Defaults to the current request URL.
318
     * @return string
319
     */
320
    public function getLogoutUrl($target = null)
321
    {
322
        $request = $this->getRequest();
323
        if (empty($target)) {
324
            $target = $request->getUri();
325
        }
326
        $logoutUrl = $this->getAttribute($this->logoutUrlAttribute);
327
        if (!empty($logoutUrl)) {
328
            return $this->getHandlerUrl() . $this->getSessionLogoutPath()
329
            . '?return=' . urlencode($logoutUrl . (empty($target) ? '' : '?return=' . $target));
330
        }
331
        return $this->getHandlerUrl() . $this->getSessionLogoutPath() . '?return=' . urlencode($target);
332
    }
333
334
    /**
335
     * Returns URL to show session.
336
     *
337
     * @return string The absolute URL to show a session
338
     */
339
    public function getOverviewUrl()
340
    {
341
        return $this->getHandlerUrl() . $this->getSessionOverviewPath();
342
    }
343
344
    /**
345
     * Returns URL to show status.
346
     *
347
     * @return string The absolute URL to show the status
348
     */
349
    public function getStatusUrl()
350
    {
351
        return $this->getHandlerUrl() . $this->getStatusPath();
352
    }
353
354
    /**
355
     * @deprecated
356
     * @return string
357
     */
358
    public function getSessionInitiatorPath()
359
    {
360
        return $this->sessionLoginPath;
361
    }
362
363
    /**
364
     * @return string
365
     */
366
    public function getUsernameAttribute()
367
    {
368
        return $this->usernameAttribute;
369
    }
370
371
    /**
372
     * @return string
373
     */
374
    public function getAuthenticatedAttribute()
375
    {
376
        return $this->authenticatedAttribute;
377
    }
378
379
    /**
380
     * @return string
381
     */
382
    public function getLogoutUrlAttribute()
383
    {
384
        return $this->logoutUrlAttribute;
385
    }
386
387
    /**
388
     * @return string
389
     */
390
    public function getAuthenticationRequirements()
391
    {
392
        return $this->authenticationRequirements;
393
    }
394
395
    /**
396
     * @return string
397
     */
398
    public function getDefaultCharset()
399
    {
400
        return $this->defaultCharset;
401
    }
402
403
    /**
404
     * @param null|string $url
405
     * @return bool
406
     */
407
    public function isReachable($url = null)
408
    {
409
        if (null === $url) {
410
            $url = $this->getStatusUrl();
411
        }
412
        $handle = curl_init($url);
413
        if (false === $handle) {
414
            return false;
415
        }
416
        curl_setopt($handle, CURLOPT_FOLLOWLOCATION, true);
417
        curl_setopt($handle, CURLOPT_HEADER, false);
418
        curl_setopt($handle, CURLOPT_FAILONERROR, true);
419
        curl_setopt($handle, CURLOPT_NOBODY, true);
420
        curl_setopt($handle, CURLOPT_RETURNTRANSFER, false);
421
        $succeeded = curl_exec($handle);
422
        curl_close($handle);
423
        if (false === $succeeded) {
424
            return false;
425
        }
426
        return true;
427
    }
428
}
429