From c51fc105f4d9a3afa29abe1430d68a1b04c8a9f2 Mon Sep 17 00:00:00 2001 From: Kris Wallsmith Date: Tue, 7 Aug 2012 14:21:04 -0400 Subject: [PATCH] avoid fatal error on invalid session --- .../Http/Firewall/ContextListener.php | 31 ++++++---- .../Http/Firewall/ContextListenerTest.php | 61 +++++++++++++++++++ 2 files changed, 80 insertions(+), 12 deletions(-) create mode 100644 tests/Symfony/Tests/Component/Security/Http/Firewall/ContextListenerTest.php diff --git a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php index 52dea564ec..1ef59957cc 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ContextListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ContextListener.php @@ -66,19 +66,26 @@ class ContextListener implements ListenerInterface if (null === $session || null === $token = $session->get('_security_'.$this->contextKey)) { $this->context->setToken(null); - } else { - if (null !== $this->logger) { - $this->logger->debug('Read SecurityContext from the session'); - } - - $token = unserialize($token); - - if (null !== $token) { - $token = $this->refreshUser($token); - } - - $this->context->setToken($token); + return; } + + $token = unserialize($token); + + if (null !== $this->logger) { + $this->logger->debug('Read SecurityContext from the session'); + } + + if ($token instanceof TokenInterface) { + $token = $this->refreshUser($token); + } elseif (null !== $token) { + if (null !== $this->logger) { + $this->logger->warn(sprintf('Session includes a "%s" where a security token is expected', is_object($value) ? get_class($value) : gettype($value))); + } + + $token = null; + } + + $this->context->setToken($token); } /** diff --git a/tests/Symfony/Tests/Component/Security/Http/Firewall/ContextListenerTest.php b/tests/Symfony/Tests/Component/Security/Http/Firewall/ContextListenerTest.php new file mode 100644 index 0000000000..040f3a8c61 --- /dev/null +++ b/tests/Symfony/Tests/Component/Security/Http/Firewall/ContextListenerTest.php @@ -0,0 +1,61 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace Symfony\Tests\Component\Security\Http\Firewall; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Http\Firewall\ContextListener; + +class ContextListenerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider provideInvalidToken + */ + public function testInvalidTokenInSession($token) + { + $context = $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'); + $event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent') + ->disableOriginalConstructor() + ->getMock(); + $request = $this->getMock('Symfony\Component\HttpFoundation\Request'); + $session = $this->getMockBuilder('Symfony\Component\HttpFoundation\Session') + ->disableOriginalConstructor() + ->getMock(); + + $event->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)); + $request->expects($this->any()) + ->method('hasPreviousSession') + ->will($this->returnValue(true)); + $request->expects($this->any()) + ->method('getSession') + ->will($this->returnValue($session)); + $session->expects($this->any()) + ->method('get') + ->with('_security_key123') + ->will($this->returnValue(serialize($token))); + $context->expects($this->once()) + ->method('setToken') + ->with(null); + + $listener = new ContextListener($context, array(), 'key123'); + $listener->handle($event); + } + + public function provideInvalidToken() + { + return array( + array(new \__PHP_Incomplete_Class()), + array(null), + ); + } +}