Merge branch '3.4' into 4.0
* 3.4: [appveyor] set memory_limit=-1 [Console] Keep the modified exception handler [Console] Fix restoring exception handler [Router] Skip anonymous classes when loading annotated routes allow dashes in cwd pathname when running the tests Fixed Request::__toString ignoring cookies Make sure we only build once and have one time the prefix when importing routes [Security] Fix fatal error on non string username [FrameworkBundle] Automatically enable the CSRF if component *+ session* are loaded
This commit is contained in:
commit
e6157aa1f7
@ -22,6 +22,7 @@ install:
|
|||||||
- 7z x php_apcu-5.1.8-7.1-ts-vc14-x86.zip -y >nul
|
- 7z x php_apcu-5.1.8-7.1-ts-vc14-x86.zip -y >nul
|
||||||
- cd ..
|
- cd ..
|
||||||
- copy /Y php.ini-development php.ini-min
|
- copy /Y php.ini-development php.ini-min
|
||||||
|
- echo memory_limit=-1 >> php.ini-min
|
||||||
- echo serialize_precision=14 >> php.ini-min
|
- echo serialize_precision=14 >> php.ini-min
|
||||||
- echo max_execution_time=1200 >> php.ini-min
|
- echo max_execution_time=1200 >> php.ini-min
|
||||||
- echo date.timezone="America/Los_Angeles" >> php.ini-min
|
- echo date.timezone="America/Los_Angeles" >> php.ini-min
|
||||||
|
@ -21,6 +21,7 @@ use Symfony\Component\Config\Definition\ConfigurationInterface;
|
|||||||
use Symfony\Component\Form\Form;
|
use Symfony\Component\Form\Form;
|
||||||
use Symfony\Component\Lock\Lock;
|
use Symfony\Component\Lock\Lock;
|
||||||
use Symfony\Component\Lock\Store\SemaphoreStore;
|
use Symfony\Component\Lock\Store\SemaphoreStore;
|
||||||
|
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
|
||||||
use Symfony\Component\Serializer\Serializer;
|
use Symfony\Component\Serializer\Serializer;
|
||||||
use Symfony\Component\Translation\Translator;
|
use Symfony\Component\Translation\Translator;
|
||||||
use Symfony\Component\Validator\Validation;
|
use Symfony\Component\Validator\Validation;
|
||||||
@ -109,7 +110,14 @@ class Configuration implements ConfigurationInterface
|
|||||||
$rootNode
|
$rootNode
|
||||||
->children()
|
->children()
|
||||||
->arrayNode('csrf_protection')
|
->arrayNode('csrf_protection')
|
||||||
->canBeEnabled()
|
->treatFalseLike(array('enabled' => false))
|
||||||
|
->treatTrueLike(array('enabled' => true))
|
||||||
|
->treatNullLike(array('enabled' => true))
|
||||||
|
->addDefaultsIfNotSet()
|
||||||
|
->children()
|
||||||
|
// defaults to framework.session.enabled && !class_exists(FullStack::class) && interface_exists(CsrfTokenManagerInterface::class)
|
||||||
|
->booleanNode('enabled')->defaultNull()->end()
|
||||||
|
->end()
|
||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
;
|
;
|
||||||
|
@ -17,6 +17,7 @@ use Symfony\Bridge\Monolog\Processor\DebugProcessor;
|
|||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
use Symfony\Bundle\FrameworkBundle\Routing\AnnotatedRouteControllerLoader;
|
use Symfony\Bundle\FrameworkBundle\Routing\AnnotatedRouteControllerLoader;
|
||||||
|
use Symfony\Bundle\FullStack;
|
||||||
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
||||||
use Symfony\Component\Cache\Adapter\AdapterInterface;
|
use Symfony\Component\Cache\Adapter\AdapterInterface;
|
||||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||||
@ -63,6 +64,7 @@ use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
|
|||||||
use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
|
use Symfony\Component\Routing\Loader\AnnotationDirectoryLoader;
|
||||||
use Symfony\Component\Routing\Loader\AnnotationFileLoader;
|
use Symfony\Component\Routing\Loader\AnnotationFileLoader;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
|
||||||
use Symfony\Component\Serializer\Encoder\DecoderInterface;
|
use Symfony\Component\Serializer\Encoder\DecoderInterface;
|
||||||
use Symfony\Component\Serializer\Encoder\EncoderInterface;
|
use Symfony\Component\Serializer\Encoder\EncoderInterface;
|
||||||
use Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory;
|
use Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory;
|
||||||
@ -183,6 +185,11 @@ class FrameworkExtension extends Extension
|
|||||||
$this->registerRequestConfiguration($config['request'], $container, $loader);
|
$this->registerRequestConfiguration($config['request'], $container, $loader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null === $config['csrf_protection']['enabled']) {
|
||||||
|
$config['csrf_protection']['enabled'] = $this->sessionConfigEnabled && !class_exists(FullStack::class) && interface_exists(CsrfTokenManagerInterface::class);
|
||||||
|
}
|
||||||
|
$this->registerSecurityCsrfConfiguration($config['csrf_protection'], $container, $loader);
|
||||||
|
|
||||||
if ($this->isConfigEnabled($container, $config['form'])) {
|
if ($this->isConfigEnabled($container, $config['form'])) {
|
||||||
if (!class_exists('Symfony\Component\Form\Form')) {
|
if (!class_exists('Symfony\Component\Form\Form')) {
|
||||||
throw new LogicException('Form support cannot be enabled as the Form component is not installed.');
|
throw new LogicException('Form support cannot be enabled as the Form component is not installed.');
|
||||||
@ -203,8 +210,6 @@ class FrameworkExtension extends Extension
|
|||||||
$container->removeDefinition('console.command.form_debug');
|
$container->removeDefinition('console.command.form_debug');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->registerSecurityCsrfConfiguration($config['csrf_protection'], $container, $loader);
|
|
||||||
|
|
||||||
if ($this->isConfigEnabled($container, $config['assets'])) {
|
if ($this->isConfigEnabled($container, $config['assets'])) {
|
||||||
if (!class_exists('Symfony\Component\Asset\Package')) {
|
if (!class_exists('Symfony\Component\Asset\Package')) {
|
||||||
throw new LogicException('Asset support cannot be enabled as the Asset component is not installed.');
|
throw new LogicException('Asset support cannot be enabled as the Asset component is not installed.');
|
||||||
|
@ -55,7 +55,7 @@ class XmlUtilsTest extends TestCase
|
|||||||
XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate'));
|
XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate'));
|
||||||
$this->fail();
|
$this->fail();
|
||||||
} catch (\InvalidArgumentException $e) {
|
} catch (\InvalidArgumentException $e) {
|
||||||
$this->assertRegExp('/The XML file "[\w:\/\\\.]+" is not valid\./', $e->getMessage());
|
$this->assertRegExp('/The XML file "[\w:\/\\\.-]+" is not valid\./', $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertInstanceOf('DOMDocument', XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate')));
|
$this->assertInstanceOf('DOMDocument', XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate')));
|
||||||
|
@ -158,10 +158,18 @@ class Application
|
|||||||
$exitCode = 1;
|
$exitCode = 1;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
// if the exception handler changed, keep it
|
||||||
|
// otherwise, unregister $renderException
|
||||||
if (!$phpHandler) {
|
if (!$phpHandler) {
|
||||||
|
if (set_exception_handler($renderException) === $renderException) {
|
||||||
|
restore_exception_handler();
|
||||||
|
}
|
||||||
restore_exception_handler();
|
restore_exception_handler();
|
||||||
} elseif (!$debugHandler) {
|
} elseif (!$debugHandler) {
|
||||||
$phpHandler[0]->setExceptionHandler(null);
|
$finalHandler = $phpHandler[0]->setExceptionHandler(null);
|
||||||
|
if ($finalHandler !== $renderException) {
|
||||||
|
$phpHandler[0]->setExceptionHandler($finalHandler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,9 +498,21 @@ class Request
|
|||||||
return trigger_error($e, E_USER_ERROR);
|
return trigger_error($e, E_USER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$cookieHeader = '';
|
||||||
|
$cookies = array();
|
||||||
|
|
||||||
|
foreach ($this->cookies as $k => $v) {
|
||||||
|
$cookies[] = $k.'='.$v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($cookies)) {
|
||||||
|
$cookieHeader = 'Cookie: '.implode('; ', $cookies)."\r\n";
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n".
|
sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n".
|
||||||
$this->headers."\r\n".
|
$this->headers.
|
||||||
|
$cookieHeader."\r\n".
|
||||||
$content;
|
$content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1507,8 +1507,18 @@ class RequestTest extends TestCase
|
|||||||
$request = new Request();
|
$request = new Request();
|
||||||
|
|
||||||
$request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
|
$request->headers->set('Accept-language', 'zh, en-us; q=0.8, en; q=0.6');
|
||||||
|
$request->cookies->set('Foo', 'Bar');
|
||||||
|
|
||||||
$this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $request->__toString());
|
$asString = (string) $request;
|
||||||
|
|
||||||
|
$this->assertContains('Accept-Language: zh, en-us; q=0.8, en; q=0.6', $asString);
|
||||||
|
$this->assertContains('Cookie: Foo=Bar', $asString);
|
||||||
|
|
||||||
|
$request->cookies->set('Another', 'Cookie');
|
||||||
|
|
||||||
|
$asString = (string) $request;
|
||||||
|
|
||||||
|
$this->assertContains('Cookie: Foo=Bar; Another=Cookie', $asString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testIsMethod()
|
public function testIsMethod()
|
||||||
|
@ -111,22 +111,22 @@ class AnnotationFileLoader extends FileLoader
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (T_CLASS === $token[0]) {
|
if (T_CLASS === $token[0]) {
|
||||||
// Skip usage of ::class constant
|
// Skip usage of ::class constant and anonymous classes
|
||||||
$isClassConstant = false;
|
$skipClassToken = false;
|
||||||
for ($j = $i - 1; $j > 0; --$j) {
|
for ($j = $i - 1; $j > 0; --$j) {
|
||||||
if (!isset($tokens[$j][1])) {
|
if (!isset($tokens[$j][1])) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (T_DOUBLE_COLON === $tokens[$j][0]) {
|
if (T_DOUBLE_COLON === $tokens[$j][0] || T_NEW === $tokens[$j][0]) {
|
||||||
$isClassConstant = true;
|
$skipClassToken = true;
|
||||||
break;
|
break;
|
||||||
} elseif (!in_array($tokens[$j][0], array(T_WHITESPACE, T_DOC_COMMENT, T_COMMENT))) {
|
} elseif (!in_array($tokens[$j][0], array(T_WHITESPACE, T_DOC_COMMENT, T_COMMENT))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$isClassConstant) {
|
if (!$skipClassToken) {
|
||||||
$class = true;
|
$class = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,10 +76,10 @@ class RouteCollectionBuilder
|
|||||||
foreach ($collection->getResources() as $resource) {
|
foreach ($collection->getResources() as $resource) {
|
||||||
$builder->addResource($resource);
|
$builder->addResource($resource);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// mount into this builder
|
// mount into this builder
|
||||||
$this->mount($prefix, $builder);
|
$this->mount($prefix, $builder);
|
||||||
}
|
|
||||||
|
|
||||||
return $builder;
|
return $builder;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
<?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\Routing\Tests\Fixtures\OtherAnnotatedClasses;
|
||||||
|
|
||||||
|
trait AnonymousClassInTrait
|
||||||
|
{
|
||||||
|
public function test()
|
||||||
|
{
|
||||||
|
return new class() {
|
||||||
|
public function foo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -61,6 +61,17 @@ class AnnotationFileLoaderTest extends AbstractAnnotationLoaderTest
|
|||||||
$this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/VariadicClass.php');
|
$this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/VariadicClass.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 7.0
|
||||||
|
*/
|
||||||
|
public function testLoadAnonymousClass()
|
||||||
|
{
|
||||||
|
$this->reader->expects($this->never())->method('getClassAnnotation');
|
||||||
|
$this->reader->expects($this->never())->method('getMethodAnnotations');
|
||||||
|
|
||||||
|
$this->loader->load(__DIR__.'/../Fixtures/OtherAnnotatedClasses/AnonymousClassInTrait.php');
|
||||||
|
}
|
||||||
|
|
||||||
public function testSupports()
|
public function testSupports()
|
||||||
{
|
{
|
||||||
$fixture = __DIR__.'/../Fixtures/annotated.php';
|
$fixture = __DIR__.'/../Fixtures/annotated.php';
|
||||||
|
@ -335,4 +335,30 @@ class RouteCollectionBuilderTest extends TestCase
|
|||||||
// there are 2 routes (i.e. with non-conflicting names)
|
// there are 2 routes (i.e. with non-conflicting names)
|
||||||
$this->assertCount(3, $collection->all());
|
$this->assertCount(3, $collection->all());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testAddsThePrefixOnlyOnceWhenLoadingMultipleCollections()
|
||||||
|
{
|
||||||
|
$firstCollection = new RouteCollection();
|
||||||
|
$firstCollection->add('a', new Route('/a'));
|
||||||
|
|
||||||
|
$secondCollection = new RouteCollection();
|
||||||
|
$secondCollection->add('b', new Route('/b'));
|
||||||
|
|
||||||
|
$loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock();
|
||||||
|
$loader->expects($this->any())
|
||||||
|
->method('supports')
|
||||||
|
->will($this->returnValue(true));
|
||||||
|
$loader
|
||||||
|
->expects($this->any())
|
||||||
|
->method('load')
|
||||||
|
->will($this->returnValue(array($firstCollection, $secondCollection)));
|
||||||
|
|
||||||
|
$routeCollectionBuilder = new RouteCollectionBuilder($loader);
|
||||||
|
$routeCollectionBuilder->import('/directory/recurse/*', '/other/', 'glob');
|
||||||
|
$routes = $routeCollectionBuilder->build()->all();
|
||||||
|
|
||||||
|
$this->assertEquals(2, count($routes));
|
||||||
|
$this->assertEquals('/other/a', $routes['a']->getPath());
|
||||||
|
$this->assertEquals('/other/b', $routes['b']->getPath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,6 @@ class ContextListener implements ListenerInterface
|
|||||||
private $registered;
|
private $registered;
|
||||||
private $trustResolver;
|
private $trustResolver;
|
||||||
|
|
||||||
private static $unserializeExceptionCode = 0x37313bc;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param TokenStorageInterface $tokenStorage
|
* @param TokenStorageInterface $tokenStorage
|
||||||
* @param iterable|UserProviderInterface[] $userProviders
|
* @param iterable|UserProviderInterface[] $userProviders
|
||||||
@ -219,7 +217,7 @@ class ContextListener implements ListenerInterface
|
|||||||
$prevUnserializeHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
|
$prevUnserializeHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback');
|
||||||
$prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = array()) use (&$prevErrorHandler) {
|
$prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = array()) use (&$prevErrorHandler) {
|
||||||
if (__FILE__ === $file) {
|
if (__FILE__ === $file) {
|
||||||
throw new \UnexpectedValueException($msg, self::$unserializeExceptionCode);
|
throw new \UnexpectedValueException($msg, 0x37313bc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : false;
|
return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : false;
|
||||||
@ -233,7 +231,7 @@ class ContextListener implements ListenerInterface
|
|||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
ini_set('unserialize_callback_func', $prevUnserializeHandler);
|
ini_set('unserialize_callback_func', $prevUnserializeHandler);
|
||||||
if ($e) {
|
if ($e) {
|
||||||
if (!$e instanceof \UnexpectedValueException || self::$unserializeExceptionCode !== $e->getCode()) {
|
if (!$e instanceof \UnexpectedValueException || 0x37313bc !== $e->getCode()) {
|
||||||
throw $e;
|
throw $e;
|
||||||
}
|
}
|
||||||
if ($this->logger) {
|
if ($this->logger) {
|
||||||
@ -249,6 +247,6 @@ class ContextListener implements ListenerInterface
|
|||||||
*/
|
*/
|
||||||
public static function handleUnserializeCallback($class)
|
public static function handleUnserializeCallback($class)
|
||||||
{
|
{
|
||||||
throw new \UnexpectedValueException('Class not found: '.$class, self::$unserializeExceptionCode);
|
throw new \UnexpectedValueException('Class not found: '.$class, 0x37313bc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Security\Http\Firewall;
|
|||||||
|
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
|
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
|
||||||
use Symfony\Component\Security\Csrf\CsrfToken;
|
use Symfony\Component\Security\Csrf\CsrfToken;
|
||||||
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
|
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
|
||||||
@ -84,15 +85,17 @@ class SimpleFormAuthenticationListener extends AbstractAuthenticationListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->options['post_only']) {
|
$requestBag = $this->options['post_only'] ? $request->request : $request;
|
||||||
$username = trim(ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']));
|
$username = ParameterBagUtils::getParameterBagValue($requestBag, $this->options['username_parameter']);
|
||||||
$password = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']);
|
$password = ParameterBagUtils::getParameterBagValue($requestBag, $this->options['password_parameter']);
|
||||||
} else {
|
|
||||||
$username = trim(ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']));
|
if (!\is_string($username) || (\is_object($username) && !\method_exists($username, '__toString'))) {
|
||||||
$password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']);
|
throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['username_parameter'], \gettype($username)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
|
$username = trim($username);
|
||||||
|
|
||||||
|
if (\strlen($username) > Security::MAX_USERNAME_LENGTH) {
|
||||||
throw new BadCredentialsException('Invalid username.');
|
throw new BadCredentialsException('Invalid username.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Security\Http\Firewall;
|
|||||||
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
use Symfony\Component\Security\Csrf\CsrfToken;
|
use Symfony\Component\Security\Csrf\CsrfToken;
|
||||||
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
|
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
|
||||||
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
|
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
|
||||||
@ -76,14 +77,16 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->options['post_only']) {
|
$requestBag = $this->options['post_only'] ? $request->request : $request;
|
||||||
$username = trim(ParameterBagUtils::getParameterBagValue($request->request, $this->options['username_parameter']));
|
$username = ParameterBagUtils::getParameterBagValue($requestBag, $this->options['username_parameter']);
|
||||||
$password = ParameterBagUtils::getParameterBagValue($request->request, $this->options['password_parameter']);
|
$password = ParameterBagUtils::getParameterBagValue($requestBag, $this->options['password_parameter']);
|
||||||
} else {
|
|
||||||
$username = trim(ParameterBagUtils::getRequestParameterValue($request, $this->options['username_parameter']));
|
if (!\is_string($username) || (\is_object($username) && !\method_exists($username, '__toString'))) {
|
||||||
$password = ParameterBagUtils::getRequestParameterValue($request, $this->options['password_parameter']);
|
throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['username_parameter'], \gettype($username)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$username = trim($username);
|
||||||
|
|
||||||
if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
|
if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
|
||||||
throw new BadCredentialsException('Invalid username.');
|
throw new BadCredentialsException('Invalid username.');
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,15 @@ namespace Symfony\Component\Security\Tests\Http\Firewall;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener;
|
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||||
|
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler;
|
||||||
|
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
|
||||||
|
use Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener;
|
||||||
|
use Symfony\Component\Security\Http\HttpUtils;
|
||||||
|
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy;
|
||||||
|
|
||||||
class UsernamePasswordFormAuthenticationListenerTest extends TestCase
|
class UsernamePasswordFormAuthenticationListenerTest extends TestCase
|
||||||
{
|
{
|
||||||
@ -69,6 +76,31 @@ class UsernamePasswordFormAuthenticationListenerTest extends TestCase
|
|||||||
$listener->handle($event);
|
$listener->handle($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
|
||||||
|
* @expectedExceptionMessage The key "_username" must be a string, "array" given.
|
||||||
|
*/
|
||||||
|
public function testHandleNonStringUsername()
|
||||||
|
{
|
||||||
|
$request = Request::create('/login_check', 'POST', array('_username' => array()));
|
||||||
|
$request->setSession($this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock());
|
||||||
|
|
||||||
|
$listener = new UsernamePasswordFormAuthenticationListener(
|
||||||
|
new TokenStorage(),
|
||||||
|
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock(),
|
||||||
|
new SessionAuthenticationStrategy(SessionAuthenticationStrategy::NONE),
|
||||||
|
$httpUtils = new HttpUtils(),
|
||||||
|
'foo',
|
||||||
|
new DefaultAuthenticationSuccessHandler($httpUtils),
|
||||||
|
new DefaultAuthenticationFailureHandler($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $httpUtils),
|
||||||
|
array('require_previous_session' => false)
|
||||||
|
);
|
||||||
|
|
||||||
|
$event = new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST);
|
||||||
|
|
||||||
|
$listener->handle($event);
|
||||||
|
}
|
||||||
|
|
||||||
public function getUsernameForLength()
|
public function getUsernameForLength()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
|
Reference in New Issue
Block a user