]> Raphaƫl G. Git Repositories - airbundle/blob - Security/LogoutSuccessHandler.php
Add note about validating app
[airbundle] / Security / LogoutSuccessHandler.php
1 <?php
2
3 namespace Rapsys\AirBundle\Security;
4
5 use Symfony\Component\HttpFoundation\RedirectResponse;
6 use Symfony\Component\HttpFoundation\Request;
7 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
8 use Symfony\Component\Routing\RouterInterface;
9 use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
10
11 class LogoutSuccessHandler implements LogoutSuccessHandlerInterface {
12 /**
13 * {@inheritdoc}
14 */
15 protected $router;
16
17 /**
18 * {@inheritdoc}
19 */
20 public function __construct(RouterInterface $router) {
21 $this->router = $router;
22 }
23
24 /**
25 * {@inheritdoc}
26 */
27 public function onLogoutSuccess(Request $request) {
28 //Retrieve logout route
29 $logout = $request->get('_route');
30
31 //Extract and process referer
32 if ($referer = $request->headers->get('referer')) {
33 //Create referer request instance
34 $req = Request::create($referer);
35
36 //Get referer path
37 $path = $req->getPathInfo();
38
39 //Get referer query string
40 $query = $req->getQueryString();
41
42 //Remove script name
43 $path = str_replace($request->getScriptName(), '', $path);
44
45 //Try with referer path
46 try {
47 //Retrieve route matching path
48 $route = $this->router->match($path);
49
50 //Verify that it differ from current one
51 if (($name = $route['_route']) == $logout) {
52 throw new ResourceNotFoundException('Identical referer and logout route');
53 }
54
55 //Remove route and controller from route defaults
56 unset($route['_route'], $route['_controller'], $route['_canonical_route']);
57
58 //Generate url
59 $url = $this->router->generate($name, $route);
60 //No route matched
61 } catch(ResourceNotFoundException $e) {
62 //Unset referer to fallback to default route
63 unset($referer);
64 }
65 }
66
67 //Referer empty or unusable
68 if (empty($referer)) {
69 //Try with / path
70 try {
71 //Retrieve route matching /
72 $route = $this->router->match('/');
73
74 //Verify that it differ from current one
75 if (($name = $route['_route']) == $logout) {
76 throw new ResourceNotFoundException('Identical referer and logout route');
77 }
78
79 //Remove route and controller from route defaults
80 unset($route['_route'], $route['_controller'], $route['_canonical_route']);
81
82 //Generate url
83 $url = $this->router->generate($name, $route);
84 //Get first route from route collection if / path was not matched
85 } catch(ResourceNotFoundException $e) {
86 //Fetch all routes
87 //XXX: this method regenerate the Routing cache making apps very slow
88 //XXX: see https://github.com/symfony/symfony-docs/issues/6710
89 //XXX: it should be fine to call it without referer and a / route
90 foreach($this->router->getRouteCollection() as $name => $route) {
91 //Return on first public route excluding logout one
92 if (!empty($name) && $name[0] != '_' && $name != $logout) {
93 break;
94 }
95 }
96
97 //Bail out if no route found
98 if (!isset($name) || !isset($route)) {
99 throw new \RuntimeException('Unable to retrieve default route');
100 }
101
102 //Retrieve route defaults
103 $defaults = $route->getDefaults();
104
105 //Remove route and controller from route defaults
106 unset($defaults['_route'], $defaults['_controller'], $defaults['_canonical_route']);
107
108 //Generate url
109 $url = $this->router->generate($name, $defaults);
110 }
111 }
112
113 //Return redirect response
114 return new RedirectResponse($url, 302);
115 }
116 }