Skip to content

Commit

Permalink
Merge branch '2.8' into 3.0
Browse files Browse the repository at this point in the history
* 2.8:
  [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

Conflicts:
	src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php
	src/Symfony/Component/ClassLoader/ClassCollectionLoader.php
  • Loading branch information
nicolas-grekas committed Jul 10, 2016
2 parents 45b9c62 + 1f2d6fb commit 06879e9
Show file tree
Hide file tree
Showing 13 changed files with 188 additions and 7 deletions.
Expand Up @@ -161,6 +161,7 @@ public function testValidateUniqueness()
$this->buildViolation('myMessage')
->atPath('property.path.name')
->setInvalidValue('Foo')
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
->assertRaised();
}

Expand All @@ -184,6 +185,7 @@ public function testValidateCustomErrorPath()
$this->buildViolation('myMessage')
->atPath('property.path.bar')
->setInvalidValue('Foo')
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
->assertRaised();
}

Expand Down Expand Up @@ -235,6 +237,7 @@ public function testValidateUniquenessWithIgnoreNull()
$this->buildViolation('myMessage')
->atPath('property.path.name')
->setInvalidValue('Foo')
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
->assertRaised();
}

Expand Down Expand Up @@ -266,6 +269,7 @@ public function testValidateUniquenessWithValidCustomErrorPath()
$this->buildViolation('myMessage')
->atPath('property.path.name2')
->setInvalidValue('Bar')
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
->assertRaised();
}

Expand Down Expand Up @@ -398,6 +402,7 @@ public function testAssociatedEntity()
$this->buildViolation('myMessage')
->atPath('property.path.single')
->setInvalidValue($entity1)
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
->assertRaised();
}

Expand Down
Expand Up @@ -23,6 +23,8 @@
*/
class UniqueEntity extends Constraint
{
const NOT_UNIQUE_ERROR = '23bd9dbf-6b9b-41cd-a99e-4844bcf3077f';

public $message = 'This value is already used.';
public $service = 'doctrine.orm.validator.unique';
public $em = null;
Expand All @@ -31,6 +33,10 @@ class UniqueEntity extends Constraint
public $errorPath = null;
public $ignoreNull = true;

protected static $errorNames = array(
self::NOT_UNIQUE_ERROR => 'NOT_UNIQUE_ERROR',
);

public function getRequiredOptions()
{
return array('fields');
Expand Down
Expand Up @@ -130,6 +130,7 @@ public function validate($entity, Constraint $constraint)
$this->context->buildViolation($constraint->message)
->atPath($errorPath)
->setInvalidValue($invalidValue)
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
->addViolation();
}
}
9 changes: 6 additions & 3 deletions src/Symfony/Component/ClassLoader/ClassCollectionLoader.php
Expand Up @@ -43,9 +43,9 @@ public static function load($classes, $cacheDir, $name, $autoReload, $adaptive =

self::$loaded[$name] = true;

$declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());

if ($adaptive) {
$declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());

// don't include already declared classes
$classes = array_diff($classes, $declared);

Expand Down Expand Up @@ -84,11 +84,14 @@ public static function load($classes, $cacheDir, $name, $autoReload, $adaptive =
}
}

if (!$reload && is_file($cache)) {
if (!$reload && file_exists($cache)) {
require_once $cache;

return;
}
if (!$adaptive) {
$declared = array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits());
}

$files = array();
$content = '';
Expand Down
5 changes: 3 additions & 2 deletions src/Symfony/Component/Form/ButtonBuilder.php
Expand Up @@ -62,11 +62,12 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
*/
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.');
}

$this->name = (string) $name;
$this->name = $name;
$this->options = $options;
}

Expand Down
61 changes: 61 additions & 0 deletions src/Symfony/Component/Form/Tests/ButtonBuilderTest.php
@@ -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);
}
}
Expand Up @@ -129,6 +129,8 @@ protected function createSubRequest($uri, Request $request)
}

$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);
if ($request->headers->has('Surrogate-Capability')) {
Expand Down
Expand Up @@ -197,6 +197,19 @@ public function testESIHeaderIsKeptInSubrequestWithTrustedHeaderDisabled()

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
Expand Down
@@ -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
);
}
}
Expand Up @@ -73,8 +73,10 @@ class CardSchemeValidator extends ConstraintValidator
'/^6[0-9]{11,18}$/',
),
// 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(
'/^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.
'VISA' => array(
Expand Down
Expand Up @@ -39,7 +39,7 @@ class PropertyMetadata extends MemberMetadata
public function __construct($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);
Expand Down
Expand Up @@ -96,6 +96,12 @@ public function getValidNumbers()
array('MAESTRO', '6594371785970435599'),
array('MASTERCARD', '5555555555554444'),
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', '4012888888881881'),
array('VISA', '4222222222222'),
Expand Down Expand Up @@ -123,6 +129,8 @@ public function getInvalidNumbers()
array('AMEX', '000000000000', CardScheme::INVALID_FORMAT_ERROR), // a lone 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('MASTERCARD', '2721001234567890', CardScheme::INVALID_FORMAT_ERROR), // Not assigned yet
array('MASTERCARD', '2220991234567890', CardScheme::INVALID_FORMAT_ERROR), // Not assigned yet
);
}
}
2 changes: 1 addition & 1 deletion src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php
Expand Up @@ -198,7 +198,7 @@ private static function filterExceptionArray($xClass, array $a, $xPrefix, $filte
'file' => $a[Caster::PREFIX_PROTECTED.'file'],
'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'])) {
unset($a[$xPrefix.'previous']);
Expand Down

0 comments on commit 06879e9

Please sign in to comment.