3 namespace Rapsys\AirBundle\Security
;
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
;
11 class LogoutSuccessHandler
implements LogoutSuccessHandlerInterface
{
20 public function __construct(RouterInterface
$router) {
21 $this->router
= $router;
27 public function onLogoutSuccess(Request
$request) {
28 //Retrieve logout route
29 $logout = $request->get('_route');
31 //Extract and process referer
32 if ($referer = $request->headers
->get('referer')) {
33 //Create referer request instance
34 $req = Request
::create($referer);
37 $path = $req->getPathInfo();
39 //Get referer query string
40 $query = $req->getQueryString();
43 $path = str_replace($request->getScriptName(), '', $path);
45 //Try with referer path
47 //Retrieve route matching path
48 $route = $this->router
->match($path);
50 //Verify that it differ from current one
51 if (($name = $route['_route']) == $logout) {
52 throw new ResourceNotFoundException('Identical referer and logout route');
55 //Remove route and controller from route defaults
56 unset($route['_route'], $route['_controller'], $route['_canonical_route']);
59 $url = $this->router
->generate($name, $route);
61 } catch(ResourceNotFoundException
$e) {
62 //Unset referer to fallback to default route
67 //Referer empty or unusable
68 if (empty($referer)) {
71 //Retrieve route matching /
72 $route = $this->router
->match('/');
74 //Verify that it differ from current one
75 if (($name = $route['_route']) == $logout) {
76 throw new ResourceNotFoundException('Identical referer and logout route');
79 //Remove route and controller from route defaults
80 unset($route['_route'], $route['_controller'], $route['_canonical_route']);
83 $url = $this->router
->generate($name, $route);
84 //Get first route from route collection if / path was not matched
85 } catch(ResourceNotFoundException
$e) {
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) {
97 //Bail out if no route found
98 if (!isset($name) || !isset($route)) {
99 throw new \
RuntimeException('Unable to retrieve default route');
102 //Retrieve route defaults
103 $defaults = $route->getDefaults();
105 //Remove route and controller from route defaults
106 unset($defaults['_route'], $defaults['_controller'], $defaults['_canonical_route']);
109 $url = $this->router
->generate($name, $defaults);
113 //Return redirect response
114 return new RedirectResponse($url, 302);