diff options
3 files changed, 233 insertions, 68 deletions
diff --git a/Guard/Authenticator/AbstractFormLoginAuthenticator.php b/Guard/Authenticator/AbstractFormLoginAuthenticator.php index d10e486..f99900b 100644 --- a/Guard/Authenticator/AbstractFormLoginAuthenticator.php +++ b/Guard/Authenticator/AbstractFormLoginAuthenticator.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Security\Guard\Authenticator; +use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Security\Guard\AbstractGuardAuthenticator; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; @@ -45,7 +46,10 @@ abstract class AbstractFormLoginAuthenticator extends AbstractGuardAuthenticator */ public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { - $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception); + if ($request->getSession() instanceof SessionInterface) { + $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception); + } + $url = $this->getLoginUrl(); return new RedirectResponse($url); @@ -65,12 +69,16 @@ abstract class AbstractFormLoginAuthenticator extends AbstractGuardAuthenticator @trigger_error(sprintf('The AbstractFormLoginAuthenticator::onAuthenticationSuccess() implementation was deprecated in Symfony 3.1 and will be removed in Symfony 4.0. You should implement this method yourself in %s and remove getDefaultSuccessRedirectUrl().', get_class($this)), E_USER_DEPRECATED); if (!method_exists($this, 'getDefaultSuccessRedirectUrl')) { - throw new \Exception(sprintf('You must implement onAuthenticationSuccess() or getDefaultSuccessRedirectURL() in %s.', get_class($this))); + throw new \Exception(sprintf('You must implement onAuthenticationSuccess() or getDefaultSuccessRedirectUrl() in %s.', get_class($this))); } - // if the user hits a secure page and start() was called, this was + $targetPath = null; + + // if the user hit a secure page and start() was called, this was // the URL they were on, and probably where you want to redirect to - $targetPath = $this->getTargetPath($request->getSession(), $providerKey); + if ($request->getSession() instanceof SessionInterface) { + $targetPath = $this->getTargetPath($request->getSession(), $providerKey); + } if (!$targetPath) { $targetPath = $this->getDefaultSuccessRedirectUrl(); diff --git a/Guard/Tests/Authenticator/AbstractFormLoginAuthenticatorTest.php b/Guard/Tests/Authenticator/AbstractFormLoginAuthenticatorTest.php deleted file mode 100644 index e86b5ad..0000000 --- a/Guard/Tests/Authenticator/AbstractFormLoginAuthenticatorTest.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php - -/* - * This file is part of the Symfony package. - * - * (c) Fabien Potencier <fabien@symfony.com> - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Security\Guard\Tests\Authenticator; - -use Symfony\Component\HttpFoundation\RedirectResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Security\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator; - -class AbstractFormLoginAuthenticatorTest extends \PHPUnit_Framework_TestCase -{ - /** - * @group legacy - */ - public function testLegacyWithLoginUrl() - { - $request = new Request(); - $request->setSession($this->getMock('Symfony\Component\HttpFoundation\Session\Session')); - - $authenticator = new LegacyFormLoginAuthenticator(); - /** @var RedirectResponse $actualResponse */ - $actualResponse = $authenticator->onAuthenticationSuccess( - $request, - $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'), - 'provider_key' - ); - - $this->assertEquals('/default_url', $actualResponse->getTargetUrl()); - } -} - -class LegacyFormLoginAuthenticator extends AbstractFormLoginAuthenticator -{ - protected function getDefaultSuccessRedirectUrl() - { - return '/default_url'; - } - - protected function getLoginUrl() - { - } - - public function getCredentials(Request $request) - { - } - - public function getUser($credentials, UserProviderInterface $userProvider) - { - } - - public function checkCredentials($credentials, UserInterface $user) - { - } -} diff --git a/Guard/Tests/Authenticator/FormLoginAuthenticatorTest.php b/Guard/Tests/Authenticator/FormLoginAuthenticatorTest.php new file mode 100644 index 0000000..e35564b --- /dev/null +++ b/Guard/Tests/Authenticator/FormLoginAuthenticatorTest.php @@ -0,0 +1,221 @@ +<?php + +/* + * This file is part of the Symfony package. + * + * (c) Fabien Potencier <fabien@symfony.com> + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Guard\Tests\Authenticator; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Core\Exception\AuthenticationException; +use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\Component\Security\Core\User\UserProviderInterface; +use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator; + +/** + * @author Jean Pasdeloup <jpasdeloup@sedona.fr> + */ +class FormLoginAuthenticatorTest extends \PHPUnit_Framework_TestCase +{ + private $requestWithoutSession; + private $requestWithSession; + private $authenticator; + + const LOGIN_URL = 'http://login'; + const DEFAULT_SUCCESS_URL = 'http://defaultsuccess'; + const CUSTOM_SUCCESS_URL = 'http://customsuccess'; + + public function testAuthenticationFailureWithoutSession() + { + $failureResponse = $this->authenticator->onAuthenticationFailure($this->requestWithoutSession, new AuthenticationException()); + + $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $failureResponse); + $this->assertEquals(self::LOGIN_URL, $failureResponse->getTargetUrl()); + } + + public function testAuthenticationFailureWithSession() + { + $this->requestWithSession->getSession() + ->expects($this->once()) + ->method('set'); + + $failureResponse = $this->authenticator->onAuthenticationFailure($this->requestWithSession, new AuthenticationException()); + + $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $failureResponse); + $this->assertEquals(self::LOGIN_URL, $failureResponse->getTargetUrl()); + } + + /** + * @group legacy + */ + public function testAuthenticationSuccessWithoutSession() + { + $token = $this->getMockBuilder('Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface') + ->disableOriginalConstructor() + ->getMock(); + + $redirectResponse = $this->authenticator->onAuthenticationSuccess($this->requestWithoutSession, $token, 'providerkey'); + + $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $redirectResponse); + $this->assertEquals(self::DEFAULT_SUCCESS_URL, $redirectResponse->getTargetUrl()); + } + + /** + * @group legacy + */ + public function testAuthenticationSuccessWithSessionButEmpty() + { + $token = $this->getMockBuilder('Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface') + ->disableOriginalConstructor() + ->getMock(); + $this->requestWithSession->getSession() + ->expects($this->once()) + ->method('get') + ->will($this->returnValue(null)); + + $redirectResponse = $this->authenticator->onAuthenticationSuccess($this->requestWithSession, $token, 'providerkey'); + + $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $redirectResponse); + $this->assertEquals(self::DEFAULT_SUCCESS_URL, $redirectResponse->getTargetUrl()); + } + + /** + * @group legacy + */ + public function testAuthenticationSuccessWithSessionAndTarget() + { + $token = $this->getMockBuilder('Symfony\\Component\\Security\\Core\\Authentication\\Token\\TokenInterface') + ->disableOriginalConstructor() + ->getMock(); + $this->requestWithSession->getSession() + ->expects($this->once()) + ->method('get') + ->will($this->returnValue(self::CUSTOM_SUCCESS_URL)); + + $redirectResponse = $this->authenticator->onAuthenticationSuccess($this->requestWithSession, $token, 'providerkey'); + + $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $redirectResponse); + $this->assertEquals(self::CUSTOM_SUCCESS_URL, $redirectResponse->getTargetUrl()); + } + + public function testRememberMe() + { + $doSupport = $this->authenticator->supportsRememberMe(); + + $this->assertTrue($doSupport); + } + + public function testStartWithoutSession() + { + $failureResponse = $this->authenticator->start($this->requestWithoutSession, new AuthenticationException()); + + $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $failureResponse); + $this->assertEquals(self::LOGIN_URL, $failureResponse->getTargetUrl()); + } + + public function testStartWithSession() + { + $failureResponse = $this->authenticator->start($this->requestWithSession, new AuthenticationException()); + + $this->assertInstanceOf('Symfony\\Component\\HttpFoundation\\RedirectResponse', $failureResponse); + $this->assertEquals(self::LOGIN_URL, $failureResponse->getTargetUrl()); + } + + protected function setUp() + { + $this->requestWithoutSession = new Request(array(), array(), array(), array(), array(), array()); + $this->requestWithSession = new Request(array(), array(), array(), array(), array(), array()); + + $session = $this->getMockBuilder('Symfony\\Component\\HttpFoundation\\Session\\SessionInterface') + ->disableOriginalConstructor() + ->getMock(); + $this->requestWithSession->setSession($session); + + $this->authenticator = new TestFormLoginAuthenticator(); + $this->authenticator + ->setLoginUrl(self::LOGIN_URL) + ->setDefaultSuccessRedirectUrl(self::DEFAULT_SUCCESS_URL) + ; + } + + protected function tearDown() + { + $this->request = null; + $this->requestWithSession = null; + } +} + +class TestFormLoginAuthenticator extends AbstractFormLoginAuthenticator +{ + private $loginUrl; + private $defaultSuccessRedirectUrl; + + /** + * @param mixed $defaultSuccessRedirectUrl + * + * @return TestFormLoginAuthenticator + */ + public function setDefaultSuccessRedirectUrl($defaultSuccessRedirectUrl) + { + $this->defaultSuccessRedirectUrl = $defaultSuccessRedirectUrl; + + return $this; + } + + /** + * @param mixed $loginUrl + * + * @return TestFormLoginAuthenticator + */ + public function setLoginUrl($loginUrl) + { + $this->loginUrl = $loginUrl; + + return $this; + } + + /** + * {@inheritdoc} + */ + protected function getLoginUrl() + { + return $this->loginUrl; + } + + /** + * {@inheritdoc} + */ + protected function getDefaultSuccessRedirectUrl() + { + return $this->defaultSuccessRedirectUrl; + } + + /** + * {@inheritdoc} + */ + public function getCredentials(Request $request) + { + return 'credentials'; + } + + /** + * {@inheritdoc} + */ + public function getUser($credentials, UserProviderInterface $userProvider) + { + return $userProvider->loadUserByUsername($credentials); + } + + /** + * {@inheritdoc} + */ + public function checkCredentials($credentials, UserInterface $user) + { + return true; + } +} |