Merge branch '2.8'
* 2.8: removed usage of the deprecated StringUtils::equals() method Fix: Resolve tempdir symlink, not working on OSX fixed tests migrate session after remember me authentication prevent timing attacks in digest auth listener mitigate CSRF timing attack vulnerability fix potential timing attack issue [WebProfilerBundle] Added a top left border radius to the minified to… [Routing] Changing RouteCollectionBuilder::import() behavior to add to the builder [HttpKernel] Don't reset on shutdown but in FrameworkBundle/Test/KernelTestCase [Process] PhpExecutableFinder: add regression test
This commit is contained in:
commit
45fe468074
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
namespace Symfony\Bundle\FrameworkBundle\Test;
|
namespace Symfony\Bundle\FrameworkBundle\Test;
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\ResettableContainerInterface;
|
||||||
use Symfony\Component\Finder\Finder;
|
use Symfony\Component\Finder\Finder;
|
||||||
use Symfony\Component\HttpKernel\KernelInterface;
|
use Symfony\Component\HttpKernel\KernelInterface;
|
||||||
|
|
||||||
|
@ -171,7 +172,11 @@ abstract class KernelTestCase extends \PHPUnit_Framework_TestCase
|
||||||
protected static function ensureKernelShutdown()
|
protected static function ensureKernelShutdown()
|
||||||
{
|
{
|
||||||
if (null !== static::$kernel) {
|
if (null !== static::$kernel) {
|
||||||
|
$container = static::$kernel->getContainer();
|
||||||
static::$kernel->shutdown();
|
static::$kernel->shutdown();
|
||||||
|
if ($container instanceof ResettableContainerInterface) {
|
||||||
|
$container->reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
.sf-minitoolbar {
|
.sf-minitoolbar {
|
||||||
background-color: #222;
|
background-color: #222;
|
||||||
|
border-top-left-radius: 4px;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
display: none;
|
display: none;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
|
@ -8,6 +9,7 @@
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: 99999;
|
z-index: 99999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sf-minitoolbar a {
|
.sf-minitoolbar a {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
@ -357,6 +359,8 @@
|
||||||
/* Override the setting when the toolbar is on the top */
|
/* Override the setting when the toolbar is on the top */
|
||||||
{% if position == 'top' %}
|
{% if position == 'top' %}
|
||||||
.sf-minitoolbar {
|
.sf-minitoolbar {
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
border-top-left-radius: 0;
|
||||||
bottom: auto;
|
bottom: auto;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
|
@ -308,7 +308,7 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
$builder = new ContainerBuilder();
|
$builder = new ContainerBuilder();
|
||||||
$builder->register('bar', 'stdClass');
|
$builder->register('bar', 'stdClass');
|
||||||
$builder->register('foo1', 'FooClass')->addMethodCall('setBar', array(array('%%unescape_it%%')));
|
$builder->register('foo1', 'Bar\FooClass')->addMethodCall('setBar', array(array('%%unescape_it%%')));
|
||||||
$builder->setParameter('value', 'bar');
|
$builder->setParameter('value', 'bar');
|
||||||
$this->assertEquals(array('%unescape_it%'), $builder->get('foo1')->bar, '->createService() replaces the values in the method calls arguments');
|
$this->assertEquals(array('%unescape_it%'), $builder->get('foo1')->bar, '->createService() replaces the values in the method calls arguments');
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
$builder = new ContainerBuilder();
|
$builder = new ContainerBuilder();
|
||||||
$builder->register('bar', 'stdClass');
|
$builder->register('bar', 'stdClass');
|
||||||
$builder->register('foo1', 'FooClass')->setProperty('bar', array('%value%', new Reference('bar'), '%%unescape_it%%'));
|
$builder->register('foo1', 'Bar\FooClass')->setProperty('bar', array('%value%', new Reference('bar'), '%%unescape_it%%'));
|
||||||
$builder->setParameter('value', 'bar');
|
$builder->setParameter('value', 'bar');
|
||||||
$this->assertEquals(array('bar', $builder->get('bar'), '%unescape_it%'), $builder->get('foo1')->bar, '->createService() replaces the values in the properties');
|
$this->assertEquals(array('bar', $builder->get('bar'), '%unescape_it%'), $builder->get('foo1')->bar, '->createService() replaces the values in the properties');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1042,8 +1042,8 @@ class FilesystemTest extends FilesystemTestCase
|
||||||
$dirname = $scheme.$this->workspace.DIRECTORY_SEPARATOR.'does_not_exist';
|
$dirname = $scheme.$this->workspace.DIRECTORY_SEPARATOR.'does_not_exist';
|
||||||
|
|
||||||
$filename = $this->filesystem->tempnam($dirname, 'bar');
|
$filename = $this->filesystem->tempnam($dirname, 'bar');
|
||||||
|
$realTempDir = realpath(sys_get_temp_dir());
|
||||||
$this->assertStringStartsWith(rtrim($scheme.sys_get_temp_dir(), DIRECTORY_SEPARATOR), $filename);
|
$this->assertStringStartsWith(rtrim($scheme.$realTempDir, DIRECTORY_SEPARATOR), $filename);
|
||||||
$this->assertFileExists($filename);
|
$this->assertFileExists($filename);
|
||||||
|
|
||||||
// Tear down
|
// Tear down
|
||||||
|
|
|
@ -23,7 +23,6 @@ use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
|
||||||
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
|
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
|
||||||
use Symfony\Component\DependencyInjection\Loader\DirectoryLoader;
|
use Symfony\Component\DependencyInjection\Loader\DirectoryLoader;
|
||||||
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
|
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
|
||||||
use Symfony\Component\DependencyInjection\ResettableContainerInterface;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
|
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
|
||||||
|
@ -155,10 +154,6 @@ abstract class Kernel implements KernelInterface, TerminableInterface
|
||||||
$bundle->setContainer(null);
|
$bundle->setContainer(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->container instanceof ResettableContainerInterface) {
|
|
||||||
$this->container->reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->container = null;
|
$this->container = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,25 @@ use Symfony\Component\Process\PhpExecutableFinder;
|
||||||
class PhpExecutableFinderTest extends \PHPUnit_Framework_TestCase
|
class PhpExecutableFinderTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* tests find() with the env var PHP_PATH.
|
* tests find() with the constant PHP_BINARY.
|
||||||
|
*/
|
||||||
|
public function testFind()
|
||||||
|
{
|
||||||
|
if (defined('HHVM_VERSION')) {
|
||||||
|
$this->markTestSkipped('Should not be executed in HHVM context.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$f = new PhpExecutableFinder();
|
||||||
|
|
||||||
|
$current = PHP_BINARY;
|
||||||
|
$args = 'phpdbg' === PHP_SAPI ? ' -qrr' : '';
|
||||||
|
|
||||||
|
$this->assertEquals($current.$args, $f->find(), '::find() returns the executable PHP');
|
||||||
|
$this->assertEquals($current, $f->find(false), '::find() returns the executable PHP');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tests find() with the env var / constant PHP_BINARY with HHVM.
|
||||||
*/
|
*/
|
||||||
public function testFindWithHHVM()
|
public function testFindWithHHVM()
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,16 +49,17 @@ class RouteCollectionBuilder
|
||||||
/**
|
/**
|
||||||
* Import an external routing resource and returns the RouteCollectionBuilder.
|
* Import an external routing resource and returns the RouteCollectionBuilder.
|
||||||
*
|
*
|
||||||
* $routes->mount('/blog', $routes->import('blog.yml'));
|
* $routes->import('blog.yml', '/blog');
|
||||||
*
|
*
|
||||||
* @param mixed $resource
|
* @param mixed $resource
|
||||||
* @param string $type
|
* @param string|null $prefix
|
||||||
|
* @param string $type
|
||||||
*
|
*
|
||||||
* @return RouteCollectionBuilder
|
* @return RouteCollectionBuilder
|
||||||
*
|
*
|
||||||
* @throws FileLoaderLoadException
|
* @throws FileLoaderLoadException
|
||||||
*/
|
*/
|
||||||
public function import($resource, $type = null)
|
public function import($resource, $prefix = '/', $type = null)
|
||||||
{
|
{
|
||||||
/** @var RouteCollection $collection */
|
/** @var RouteCollection $collection */
|
||||||
$collection = $this->load($resource, $type);
|
$collection = $this->load($resource, $type);
|
||||||
|
@ -73,6 +74,9 @@ class RouteCollectionBuilder
|
||||||
$builder->addResource($resource);
|
$builder->addResource($resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mount into this builder
|
||||||
|
$this->mount($prefix, $builder);
|
||||||
|
|
||||||
return $builder;
|
return $builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ class RouteCollectionBuilderTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
// import the file!
|
// import the file!
|
||||||
$routes = new RouteCollectionBuilder($loader);
|
$routes = new RouteCollectionBuilder($loader);
|
||||||
$importedRoutes = $routes->import('admin_routing.yml', 'yaml');
|
$importedRoutes = $routes->import('admin_routing.yml', '/', 'yaml');
|
||||||
|
|
||||||
// we should get back a RouteCollectionBuilder
|
// we should get back a RouteCollectionBuilder
|
||||||
$this->assertInstanceOf('Symfony\Component\Routing\RouteCollectionBuilder', $importedRoutes);
|
$this->assertInstanceOf('Symfony\Component\Routing\RouteCollectionBuilder', $importedRoutes);
|
||||||
|
@ -56,6 +56,9 @@ class RouteCollectionBuilderTest extends \PHPUnit_Framework_TestCase
|
||||||
$this->assertSame($originalRoute, $route);
|
$this->assertSame($originalRoute, $route);
|
||||||
// should return file_resource.yml, which is in the original collection
|
// should return file_resource.yml, which is in the original collection
|
||||||
$this->assertCount(1, $addedCollection->getResources());
|
$this->assertCount(1, $addedCollection->getResources());
|
||||||
|
|
||||||
|
// make sure the routes were imported into the top-level builder
|
||||||
|
$this->assertCount(1, $routes->build());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -285,7 +288,7 @@ class RouteCollectionBuilderTest extends \PHPUnit_Framework_TestCase
|
||||||
->method('load')
|
->method('load')
|
||||||
->will($this->returnValue($importedCollection));
|
->will($this->returnValue($importedCollection));
|
||||||
// import this from the /admin route builder
|
// import this from the /admin route builder
|
||||||
$adminRoutes->mount('/imported', $adminRoutes->import('admin.yml'));
|
$adminRoutes->import('admin.yml', '/imported');
|
||||||
|
|
||||||
$collection = $routes->build();
|
$collection = $routes->build();
|
||||||
$this->assertEquals('/admin/dashboard', $collection->get('admin_dashboard')->getPath(), 'Routes before mounting have the prefix');
|
$this->assertEquals('/admin/dashboard', $collection->get('admin_dashboard')->getPath(), 'Routes before mounting have the prefix');
|
||||||
|
|
|
@ -99,7 +99,7 @@ class DigestAuthenticationListener implements ListenerInterface
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($serverDigestMd5 !== $digestAuth->getResponse()) {
|
if (!hash_equals($serverDigestMd5, $digestAuth->getResponse())) {
|
||||||
if (null !== $this->logger) {
|
if (null !== $this->logger) {
|
||||||
$this->logger->debug('Unexpected response from the DigestAuth received; is the header returning a clear text passwords?', array('expected' => $serverDigestMd5, 'received' => $digestAuth->getResponse()));
|
$this->logger->debug('Unexpected response from the DigestAuth received; is the header returning a clear text passwords?', array('expected' => $serverDigestMd5, 'received' => $digestAuth->getResponse()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
|
||||||
use Symfony\Component\Security\Http\SecurityEvents;
|
use Symfony\Component\Security\Http\SecurityEvents;
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
|
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
|
||||||
|
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RememberMeListener implements authentication capabilities via a cookie.
|
* RememberMeListener implements authentication capabilities via a cookie.
|
||||||
|
@ -56,7 +57,7 @@ class RememberMeListener implements ListenerInterface
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
$this->dispatcher = $dispatcher;
|
$this->dispatcher = $dispatcher;
|
||||||
$this->catchExceptions = $catchExceptions;
|
$this->catchExceptions = $catchExceptions;
|
||||||
$this->sessionStrategy = $sessionStrategy;
|
$this->sessionStrategy = null === $sessionStrategy ? new SessionAuthenticationStrategy(SessionAuthenticationStrategy::MIGRATE) : $sessionStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -77,7 +78,7 @@ class RememberMeListener implements ListenerInterface
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$token = $this->authenticationManager->authenticate($token);
|
$token = $this->authenticationManager->authenticate($token);
|
||||||
if (null !== $this->sessionStrategy && $request->hasSession() && $request->getSession()->isStarted()) {
|
if ($request->hasSession() && $request->getSession()->isStarted()) {
|
||||||
$this->sessionStrategy->onAuthentication($request, $token);
|
$this->sessionStrategy->onAuthentication($request, $token);
|
||||||
}
|
}
|
||||||
$this->tokenStorage->setToken($token);
|
$this->tokenStorage->setToken($token);
|
||||||
|
|
|
@ -71,7 +71,7 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices
|
||||||
list($series, $tokenValue) = $cookieParts;
|
list($series, $tokenValue) = $cookieParts;
|
||||||
$persistentToken = $this->tokenProvider->loadTokenBySeries($series);
|
$persistentToken = $this->tokenProvider->loadTokenBySeries($series);
|
||||||
|
|
||||||
if ($persistentToken->getTokenValue() !== $tokenValue) {
|
if (!hash_equals($persistentToken->getTokenValue(), $tokenValue)) {
|
||||||
throw new CookieTheftException('This token was already used. The account is possibly compromised.');
|
throw new CookieTheftException('This token was already used. The account is possibly compromised.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,6 +246,69 @@ class RememberMeListenerTest extends \PHPUnit_Framework_TestCase
|
||||||
$listener->handle($event);
|
$listener->handle($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSessionIsMigratedByDefault()
|
||||||
|
{
|
||||||
|
list($listener, $tokenStorage, $service, $manager, , $dispatcher, $sessionStrategy) = $this->getListener(false, true, false);
|
||||||
|
|
||||||
|
$tokenStorage
|
||||||
|
->expects($this->once())
|
||||||
|
->method('getToken')
|
||||||
|
->will($this->returnValue(null))
|
||||||
|
;
|
||||||
|
|
||||||
|
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
|
||||||
|
$service
|
||||||
|
->expects($this->once())
|
||||||
|
->method('autoLogin')
|
||||||
|
->will($this->returnValue($token))
|
||||||
|
;
|
||||||
|
|
||||||
|
$tokenStorage
|
||||||
|
->expects($this->once())
|
||||||
|
->method('setToken')
|
||||||
|
->with($this->equalTo($token))
|
||||||
|
;
|
||||||
|
|
||||||
|
$manager
|
||||||
|
->expects($this->once())
|
||||||
|
->method('authenticate')
|
||||||
|
->will($this->returnValue($token))
|
||||||
|
;
|
||||||
|
|
||||||
|
$session = $this->getMock('\Symfony\Component\HttpFoundation\Session\SessionInterface');
|
||||||
|
$session
|
||||||
|
->expects($this->once())
|
||||||
|
->method('isStarted')
|
||||||
|
->will($this->returnValue(true))
|
||||||
|
;
|
||||||
|
$session
|
||||||
|
->expects($this->once())
|
||||||
|
->method('migrate')
|
||||||
|
;
|
||||||
|
|
||||||
|
$request = $this->getMock('\Symfony\Component\HttpFoundation\Request');
|
||||||
|
$request
|
||||||
|
->expects($this->any())
|
||||||
|
->method('hasSession')
|
||||||
|
->will($this->returnValue(true))
|
||||||
|
;
|
||||||
|
|
||||||
|
$request
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getSession')
|
||||||
|
->will($this->returnValue($session))
|
||||||
|
;
|
||||||
|
|
||||||
|
$event = $this->getGetResponseEvent();
|
||||||
|
$event
|
||||||
|
->expects($this->once())
|
||||||
|
->method('getRequest')
|
||||||
|
->will($this->returnValue($request))
|
||||||
|
;
|
||||||
|
|
||||||
|
$listener->handle($event);
|
||||||
|
}
|
||||||
|
|
||||||
public function testOnCoreSecurityInteractiveLoginEventIsDispatchedIfDispatcherIsPresent()
|
public function testOnCoreSecurityInteractiveLoginEventIsDispatchedIfDispatcherIsPresent()
|
||||||
{
|
{
|
||||||
list($listener, $tokenStorage, $service, $manager, , $dispatcher) = $this->getListener(true);
|
list($listener, $tokenStorage, $service, $manager, , $dispatcher) = $this->getListener(true);
|
||||||
|
|
Reference in New Issue