Merge branch '3.0' into 3.1
* 3.0: [HttpKernel] fixed internal subrequests having an if-modified-since-header [Security] Fix deprecated usage of DigestAuthenticationEntryPoint::getKey() in DigestAuthenticationListener [Validator] Added additional MasterCard range to the CardSchemeValidator Make the exception message more clear. [Form] fixed bug - name in ButtonBuilder [DoctrineBridge] added missing error code for constraint. [ClassLoader] Fix declared classes being computed when not needed [varDumper] Fix missing usage of ExceptionCaster::$traceArgs
This commit is contained in:
commit
f2599e4db2
@ -166,6 +166,7 @@ class UniqueEntityValidatorTest extends AbstractConstraintValidatorTest
|
|||||||
->atPath('property.path.name')
|
->atPath('property.path.name')
|
||||||
->setParameter('{{ value }}', 'Foo')
|
->setParameter('{{ value }}', 'Foo')
|
||||||
->setInvalidValue('Foo')
|
->setInvalidValue('Foo')
|
||||||
|
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
|
||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,6 +191,7 @@ class UniqueEntityValidatorTest extends AbstractConstraintValidatorTest
|
|||||||
->atPath('property.path.bar')
|
->atPath('property.path.bar')
|
||||||
->setParameter('{{ value }}', 'Foo')
|
->setParameter('{{ value }}', 'Foo')
|
||||||
->setInvalidValue('Foo')
|
->setInvalidValue('Foo')
|
||||||
|
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
|
||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,6 +244,7 @@ class UniqueEntityValidatorTest extends AbstractConstraintValidatorTest
|
|||||||
->atPath('property.path.name')
|
->atPath('property.path.name')
|
||||||
->setParameter('{{ value }}', 'Foo')
|
->setParameter('{{ value }}', 'Foo')
|
||||||
->setInvalidValue('Foo')
|
->setInvalidValue('Foo')
|
||||||
|
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
|
||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,6 +277,7 @@ class UniqueEntityValidatorTest extends AbstractConstraintValidatorTest
|
|||||||
->atPath('property.path.name2')
|
->atPath('property.path.name2')
|
||||||
->setParameter('{{ value }}', 'Bar')
|
->setParameter('{{ value }}', 'Bar')
|
||||||
->setInvalidValue('Bar')
|
->setInvalidValue('Bar')
|
||||||
|
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
|
||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,6 +411,7 @@ class UniqueEntityValidatorTest extends AbstractConstraintValidatorTest
|
|||||||
->atPath('property.path.single')
|
->atPath('property.path.single')
|
||||||
->setParameter('{{ value }}', $entity1)
|
->setParameter('{{ value }}', $entity1)
|
||||||
->setInvalidValue($entity1)
|
->setInvalidValue($entity1)
|
||||||
|
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
|
||||||
->assertRaised();
|
->assertRaised();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@ use Symfony\Component\Validator\Constraint;
|
|||||||
*/
|
*/
|
||||||
class UniqueEntity extends Constraint
|
class UniqueEntity extends Constraint
|
||||||
{
|
{
|
||||||
|
const NOT_UNIQUE_ERROR = '23bd9dbf-6b9b-41cd-a99e-4844bcf3077f';
|
||||||
|
|
||||||
public $message = 'This value is already used.';
|
public $message = 'This value is already used.';
|
||||||
public $service = 'doctrine.orm.validator.unique';
|
public $service = 'doctrine.orm.validator.unique';
|
||||||
public $em = null;
|
public $em = null;
|
||||||
@ -31,6 +33,10 @@ class UniqueEntity extends Constraint
|
|||||||
public $errorPath = null;
|
public $errorPath = null;
|
||||||
public $ignoreNull = true;
|
public $ignoreNull = true;
|
||||||
|
|
||||||
|
protected static $errorNames = array(
|
||||||
|
self::NOT_UNIQUE_ERROR => 'NOT_UNIQUE_ERROR',
|
||||||
|
);
|
||||||
|
|
||||||
public function getRequiredOptions()
|
public function getRequiredOptions()
|
||||||
{
|
{
|
||||||
return array('fields');
|
return array('fields');
|
||||||
|
@ -135,6 +135,7 @@ class UniqueEntityValidator extends ConstraintValidator
|
|||||||
->atPath($errorPath)
|
->atPath($errorPath)
|
||||||
->setParameter('{{ value }}', $invalidValue)
|
->setParameter('{{ value }}', $invalidValue)
|
||||||
->setInvalidValue($invalidValue)
|
->setInvalidValue($invalidValue)
|
||||||
|
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
|
||||||
->addViolation();
|
->addViolation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,9 @@ class ClassCollectionLoader
|
|||||||
|
|
||||||
self::$loaded[$name] = true;
|
self::$loaded[$name] = true;
|
||||||
|
|
||||||
$declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
|
|
||||||
|
|
||||||
if ($adaptive) {
|
if ($adaptive) {
|
||||||
|
$declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
|
||||||
|
|
||||||
// don't include already declared classes
|
// don't include already declared classes
|
||||||
$classes = array_diff($classes, $declared);
|
$classes = array_diff($classes, $declared);
|
||||||
|
|
||||||
@ -84,11 +84,14 @@ class ClassCollectionLoader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$reload && is_file($cache)) {
|
if (!$reload && file_exists($cache)) {
|
||||||
require_once $cache;
|
require_once $cache;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!$adaptive) {
|
||||||
|
$declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
|
||||||
|
}
|
||||||
|
|
||||||
$files = array();
|
$files = array();
|
||||||
$content = '';
|
$content = '';
|
||||||
|
@ -62,11 +62,12 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
|
|||||||
*/
|
*/
|
||||||
public function __construct($name, array $options = array())
|
public function __construct($name, array $options = array())
|
||||||
{
|
{
|
||||||
if (empty($name) && 0 != $name) {
|
$name = (string) $name;
|
||||||
|
if ('' === $name) {
|
||||||
throw new InvalidArgumentException('Buttons cannot have empty names.');
|
throw new InvalidArgumentException('Buttons cannot have empty names.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->name = (string) $name;
|
$this->name = $name;
|
||||||
$this->options = $options;
|
$this->options = $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
61
src/Symfony/Component/Form/Tests/ButtonBuilderTest.php
Normal file
61
src/Symfony/Component/Form/Tests/ButtonBuilderTest.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?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\Form\Tests;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\ButtonBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Alexander Cheprasov <cheprasov.84@ya.ru>
|
||||||
|
*/
|
||||||
|
class ButtonBuilderTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function getValidNames()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('reset'),
|
||||||
|
array('submit'),
|
||||||
|
array('foo'),
|
||||||
|
array('0'),
|
||||||
|
array(0),
|
||||||
|
array('button[]'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getValidNames
|
||||||
|
*/
|
||||||
|
public function testValidNames($name)
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf('\Symfony\Component\Form\ButtonBuilder', new ButtonBuilder($name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getInvalidNames()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array(''),
|
||||||
|
array(false),
|
||||||
|
array(null),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getInvalidNames
|
||||||
|
*/
|
||||||
|
public function testInvalidNames($name)
|
||||||
|
{
|
||||||
|
$this->setExpectedException(
|
||||||
|
'\Symfony\Component\Form\Exception\InvalidArgumentException',
|
||||||
|
'Buttons cannot have empty names.'
|
||||||
|
);
|
||||||
|
new ButtonBuilder($name);
|
||||||
|
}
|
||||||
|
}
|
@ -129,6 +129,8 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
$server['REMOTE_ADDR'] = '127.0.0.1';
|
$server['REMOTE_ADDR'] = '127.0.0.1';
|
||||||
|
unset($server['HTTP_IF_MODIFIED_SINCE']);
|
||||||
|
unset($server['HTTP_IF_NONE_MATCH']);
|
||||||
|
|
||||||
$subRequest = Request::create($uri, 'get', array(), $cookies, array(), $server);
|
$subRequest = Request::create($uri, 'get', array(), $cookies, array(), $server);
|
||||||
if ($request->headers->has('Surrogate-Capability')) {
|
if ($request->headers->has('Surrogate-Capability')) {
|
||||||
|
@ -226,6 +226,19 @@ class InlineFragmentRendererTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, $trustedHeaderName);
|
Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, $trustedHeaderName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testHeadersPossiblyResultingIn304AreNotAssignedToSubrequest()
|
||||||
|
{
|
||||||
|
$expectedSubRequest = Request::create('/');
|
||||||
|
if (Request::getTrustedHeaderName(Request::HEADER_CLIENT_IP)) {
|
||||||
|
$expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
|
||||||
|
$expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
|
||||||
|
}
|
||||||
|
|
||||||
|
$strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest));
|
||||||
|
$request = Request::create('/', 'GET', array(), array(), array(), array('HTTP_IF_MODIFIED_SINCE' => 'Fri, 01 Jan 2016 00:00:00 GMT', 'HTTP_IF_NONE_MATCH' => '*'));
|
||||||
|
$strategy->render('/', $request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Bar
|
class Bar
|
||||||
|
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\Security\Http\Tests\Firewall;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
||||||
|
use Symfony\Component\Security\Http\EntryPoint\DigestAuthenticationEntryPoint;
|
||||||
|
use Symfony\Component\Security\Http\Firewall\DigestAuthenticationListener;
|
||||||
|
|
||||||
|
class DigestAuthenticationListenerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testHandleWithValidDigest()
|
||||||
|
{
|
||||||
|
$time = microtime(true) + 1000;
|
||||||
|
$secret = 'ThisIsASecret';
|
||||||
|
$nonce = base64_encode($time.':'.md5($time.':'.$secret));
|
||||||
|
$username = 'user';
|
||||||
|
$password = 'password';
|
||||||
|
$realm = 'Welcome, robot!';
|
||||||
|
$cnonce = 'MDIwODkz';
|
||||||
|
$nc = '00000001';
|
||||||
|
$qop = 'auth';
|
||||||
|
$uri = '/path/info?p1=5&p2=5';
|
||||||
|
|
||||||
|
$serverDigest = $this->calculateServerDigest($username, $realm, $password, $nc, $nonce, $cnonce, $qop, 'GET', $uri);
|
||||||
|
|
||||||
|
$digestData =
|
||||||
|
'username="'.$username.'", realm="'.$realm.'", nonce="'.$nonce.'", '.
|
||||||
|
'uri="'.$uri.'", cnonce="'.$cnonce.'", nc='.$nc.', qop="'.$qop.'", '.
|
||||||
|
'response="'.$serverDigest.'"'
|
||||||
|
;
|
||||||
|
|
||||||
|
$request = new Request(array(), array(), array(), array(), array(), array('PHP_AUTH_DIGEST' => $digestData));
|
||||||
|
|
||||||
|
$entryPoint = new DigestAuthenticationEntryPoint($realm, $secret);
|
||||||
|
|
||||||
|
$user = $this->getMock('Symfony\Component\Security\Core\User\UserInterface');
|
||||||
|
$user->method('getPassword')->willReturn($password);
|
||||||
|
|
||||||
|
$providerKey = 'TheProviderKey';
|
||||||
|
|
||||||
|
$tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
|
||||||
|
$tokenStorage
|
||||||
|
->expects($this->once())
|
||||||
|
->method('getToken')
|
||||||
|
->will($this->returnValue(null))
|
||||||
|
;
|
||||||
|
$tokenStorage
|
||||||
|
->expects($this->once())
|
||||||
|
->method('setToken')
|
||||||
|
->with($this->equalTo(new UsernamePasswordToken($user, $password, $providerKey)))
|
||||||
|
;
|
||||||
|
|
||||||
|
$userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface');
|
||||||
|
$userProvider->method('loadUserByUsername')->willReturn($user);
|
||||||
|
|
||||||
|
$listener = new DigestAuthenticationListener($tokenStorage, $userProvider, $providerKey, $entryPoint);
|
||||||
|
|
||||||
|
$event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false);
|
||||||
|
$event
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getRequest')
|
||||||
|
->will($this->returnValue($request))
|
||||||
|
;
|
||||||
|
|
||||||
|
$listener->handle($event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function calculateServerDigest($username, $realm, $password, $nc, $nonce, $cnonce, $qop, $method, $uri)
|
||||||
|
{
|
||||||
|
$response = md5(
|
||||||
|
md5($username.':'.$realm.':'.$password).':'.$nonce.':'.$nc.':'.$cnonce.':'.$qop.':'.md5($method.':'.$uri)
|
||||||
|
);
|
||||||
|
|
||||||
|
return sprintf('username="%s", realm="%s", nonce="%s", uri="%s", cnonce="%s", nc=%s, qop="%s", response="%s"',
|
||||||
|
$username, $realm, $nonce, $uri, $cnonce, $nc, $qop, $response
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -73,8 +73,10 @@ class CardSchemeValidator extends ConstraintValidator
|
|||||||
'/^6[0-9]{11,18}$/',
|
'/^6[0-9]{11,18}$/',
|
||||||
),
|
),
|
||||||
// All MasterCard numbers start with the numbers 51 through 55. All have 16 digits.
|
// All MasterCard numbers start with the numbers 51 through 55. All have 16 digits.
|
||||||
|
// October 2016 MasterCard numbers can also start with 222100 through 272099.
|
||||||
'MASTERCARD' => array(
|
'MASTERCARD' => array(
|
||||||
'/^5[1-5][0-9]{14}$/',
|
'/^5[1-5][0-9]{14}$/',
|
||||||
|
'/^2(22[1-9][0-9]{12}|2[3-9][0-9]{13}|[3-6][0-9]{14}|7[0-1][0-9]{13}|720[0-9]{12})$/',
|
||||||
),
|
),
|
||||||
// All Visa card numbers start with a 4. New cards have 16 digits. Old cards have 13.
|
// All Visa card numbers start with a 4. New cards have 16 digits. Old cards have 13.
|
||||||
'VISA' => array(
|
'VISA' => array(
|
||||||
|
@ -39,7 +39,7 @@ class PropertyMetadata extends MemberMetadata
|
|||||||
public function __construct($class, $name)
|
public function __construct($class, $name)
|
||||||
{
|
{
|
||||||
if (!property_exists($class, $name)) {
|
if (!property_exists($class, $name)) {
|
||||||
throw new ValidatorException(sprintf('Property %s does not exist in class %s', $name, $class));
|
throw new ValidatorException(sprintf('Property "%s" does not exist in class "%s"', $name, $class));
|
||||||
}
|
}
|
||||||
|
|
||||||
parent::__construct($class, $name, $name);
|
parent::__construct($class, $name, $name);
|
||||||
|
@ -96,6 +96,12 @@ class CardSchemeValidatorTest extends AbstractConstraintValidatorTest
|
|||||||
array('MAESTRO', '6594371785970435599'),
|
array('MAESTRO', '6594371785970435599'),
|
||||||
array('MASTERCARD', '5555555555554444'),
|
array('MASTERCARD', '5555555555554444'),
|
||||||
array('MASTERCARD', '5105105105105100'),
|
array('MASTERCARD', '5105105105105100'),
|
||||||
|
array('MASTERCARD', '2221005555554444'),
|
||||||
|
array('MASTERCARD', '2230000000000000'),
|
||||||
|
array('MASTERCARD', '2300000000000000'),
|
||||||
|
array('MASTERCARD', '2699999999999999'),
|
||||||
|
array('MASTERCARD', '2709999999999999'),
|
||||||
|
array('MASTERCARD', '2720995105105100'),
|
||||||
array('VISA', '4111111111111111'),
|
array('VISA', '4111111111111111'),
|
||||||
array('VISA', '4012888888881881'),
|
array('VISA', '4012888888881881'),
|
||||||
array('VISA', '4222222222222'),
|
array('VISA', '4222222222222'),
|
||||||
@ -123,6 +129,8 @@ class CardSchemeValidatorTest extends AbstractConstraintValidatorTest
|
|||||||
array('AMEX', '000000000000', CardScheme::INVALID_FORMAT_ERROR), // a lone number
|
array('AMEX', '000000000000', CardScheme::INVALID_FORMAT_ERROR), // a lone number
|
||||||
array('DINERS', '3056930', CardScheme::INVALID_FORMAT_ERROR), // only first part of the number
|
array('DINERS', '3056930', CardScheme::INVALID_FORMAT_ERROR), // only first part of the number
|
||||||
array('DISCOVER', '1117', CardScheme::INVALID_FORMAT_ERROR), // only last 4 digits
|
array('DISCOVER', '1117', CardScheme::INVALID_FORMAT_ERROR), // only last 4 digits
|
||||||
|
array('MASTERCARD', '2721001234567890', CardScheme::INVALID_FORMAT_ERROR), // Not assigned yet
|
||||||
|
array('MASTERCARD', '2220991234567890', CardScheme::INVALID_FORMAT_ERROR), // Not assigned yet
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ class ExceptionCaster
|
|||||||
'file' => $a[Caster::PREFIX_PROTECTED.'file'],
|
'file' => $a[Caster::PREFIX_PROTECTED.'file'],
|
||||||
'line' => $a[Caster::PREFIX_PROTECTED.'line'],
|
'line' => $a[Caster::PREFIX_PROTECTED.'line'],
|
||||||
));
|
));
|
||||||
$a[$xPrefix.'trace'] = new TraceStub($trace);
|
$a[$xPrefix.'trace'] = new TraceStub($trace, self::$traceArgs);
|
||||||
}
|
}
|
||||||
if (empty($a[$xPrefix.'previous'])) {
|
if (empty($a[$xPrefix.'previous'])) {
|
||||||
unset($a[$xPrefix.'previous']);
|
unset($a[$xPrefix.'previous']);
|
||||||
|
Reference in New Issue
Block a user