diff --git a/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php b/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php index 2aa3ac621fc10..08e08f7454c3a 100644 --- a/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php +++ b/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php @@ -131,8 +131,6 @@ private function handleAccessDeniedException(GetResponseForExceptionEvent $event } catch (\Exception $e) { $event->setException($e); } - - return; } if (null !== $this->logger) { @@ -150,7 +148,7 @@ private function handleAccessDeniedException(GetResponseForExceptionEvent $event $subRequest = $this->httpUtils->createRequest($event->getRequest(), $this->errorPage); $subRequest->attributes->set(Security::ACCESS_DENIED_ERROR, $exception); - $event->setResponse($event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true)); + $event->setResponse($event->getKernel()->handle($subRequest, HttpKernelInterface::SUB_REQUEST)); $event->allowCustomResponseCode(); } } catch (\Exception $e) { diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php index 53fedebcad705..6812405ff7e34 100644 --- a/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php @@ -130,10 +130,15 @@ public function testAccessDeniedExceptionFullFledgedAndWithAccessDeniedHandlerAn { $event = $this->createEvent($exception); - $accessDeniedHandler = $this->getMockBuilder('Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface')->getMock(); - $accessDeniedHandler->expects($this->once())->method('handle')->will($this->returnValue(new Response('error'))); + $listener = $this->createExceptionListener( + null, + $this->createTrustResolver(true), + null, + null, + null, + $this->createCustomAccessDeniedHandler(new Response('error')) + ); - $listener = $this->createExceptionListener(null, $this->createTrustResolver(true), null, null, null, $accessDeniedHandler); $listener->onKernelException($event); $this->assertEquals('error', $event->getResponse()->getContent()); @@ -147,16 +152,70 @@ public function testAccessDeniedExceptionNotFullFledged(\Exception $exception, \ { $event = $this->createEvent($exception); - $tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(); - $tokenStorage->expects($this->once())->method('getToken')->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock())); - - $listener = $this->createExceptionListener($tokenStorage, $this->createTrustResolver(false), null, $this->createEntryPoint()); + $listener = $this->createExceptionListener( + $this->createTokenStorage(), + $this->createTrustResolver(false), + null, + $this->createEntryPoint() + ); $listener->onKernelException($event); $this->assertEquals('OK', $event->getResponse()->getContent()); $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious()); } + /** + * @dataProvider getAccessDeniedExceptionProvider + */ + public function testAccessDeniedExceptionNotFullFledgedAndWithAccessDeniedHandlerAndWithoutErrorPage(\Exception $exception, \Exception $eventException = null) + { + $event = $this->createEvent($exception); + + $listener = $this->createExceptionListener( + $this->createTokenStorage(), + $this->createTrustResolver(false), + null, + $this->createEntryPoint(), + null, + $this->createCustomAccessDeniedHandler(new Response('denied', 403)) + ); + $listener->onKernelException($event); + + $this->assertEquals('denied', $event->getResponse()->getContent()); + $this->assertEquals(403, $event->getResponse()->getStatusCode()); + $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious()); + } + + + /** + * @dataProvider getAccessDeniedExceptionProvider + */ + public function testAccessDeniedExceptionNotFullFledgedAndWithoutAccessDeniedHandlerAndWithErrorPage(\Exception $exception, \Exception $eventException = null) + { + $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(); + $kernel->expects($this->once())->method('handle')->will($this->returnValue(new Response('Unauthorized', 401))); + + $event = $this->createEvent($exception, $kernel); + + $httpUtils = $this->getMockBuilder('Symfony\Component\Security\Http\HttpUtils')->getMock(); + $httpUtils->expects($this->once())->method('createRequest')->will($this->returnValue(Request::create('/error'))); + + $listener = $this->createExceptionListener( + $this->createTokenStorage(), + $this->createTrustResolver(true), + $httpUtils, + null, + '/error' + ); + $listener->onKernelException($event); + + $this->assertTrue($event->isAllowingCustomResponseCode()); + + $this->assertEquals('Unauthorized', $event->getResponse()->getContent()); + $this->assertEquals(401, $event->getResponse()->getStatusCode()); + $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious()); + } + public function getAccessDeniedExceptionProvider() { return [ @@ -168,6 +227,28 @@ public function getAccessDeniedExceptionProvider() ]; } + private function createTokenStorage() + { + $tokenStorage = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(); + $tokenStorage + ->expects($this->once()) + ->method('getToken') + ->will($this->returnValue($this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\TokenInterface')->getMock())); + + return $tokenStorage; + } + + private function createCustomAccessDeniedHandler(Response $response) + { + $accessDeniedHandler = $this->getMockBuilder('Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface')->getMock(); + $accessDeniedHandler + ->expects($this->once()) + ->method('handle') + ->will($this->returnValue($response)); + + return $accessDeniedHandler; + } + private function createEntryPoint(Response $response = null) { $entryPoint = $this->getMockBuilder('Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface')->getMock(); @@ -193,8 +274,14 @@ private function createEvent(\Exception $exception, $kernel = null) return new GetResponseForExceptionEvent($kernel, Request::create('/'), HttpKernelInterface::MASTER_REQUEST, $exception); } - private function createExceptionListener(TokenStorageInterface $tokenStorage = null, AuthenticationTrustResolverInterface $trustResolver = null, HttpUtils $httpUtils = null, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null) - { + private function createExceptionListener( + TokenStorageInterface $tokenStorage = null, + AuthenticationTrustResolverInterface $trustResolver = null, + HttpUtils $httpUtils = null, + AuthenticationEntryPointInterface $authenticationEntryPoint = null, + $errorPage = null, + AccessDeniedHandlerInterface $accessDeniedHandler = null + ) { return new ExceptionListener( $tokenStorage ?: $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')->getMock(), $trustResolver ?: $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface')->getMock(),