Skip to content

Commit

Permalink
Merge branch '3.4' into 4.0
Browse files Browse the repository at this point in the history
* 3.4:
  fix merge
  [Security] Fix logout
  Cleanup 2 tests for the HttpException classes
  #27250 limiting GET_LOCK key up to 64 char due to changes in MySQL 5.7.5 and later
  [Config] Fix tests when path contains UTF chars
  [DI] Shared services should not be inlined in non-shared ones
  [Profiler] Remove propel & event_listener_loading category identifiers
  [Filesystem] Fix usages of error_get_last()
  [Cache][Lock] Fix usages of error_get_last()
  [Debug] Fix populating error_get_last() for handled silent errors
  [DI] Display previous error messages when throwing unused bindings
  Suppress warnings when open_basedir is non-empty
  • Loading branch information
nicolas-grekas committed May 16, 2018
2 parents 4f3afd5 + bf2943e commit 8c430fb
Show file tree
Hide file tree
Showing 37 changed files with 312 additions and 122 deletions.
Expand Up @@ -184,14 +184,15 @@ private function createFirewalls($config, ContainerBuilder $container)

$configId = 'security.firewall.map.config.'.$name;

list($matcher, $listeners, $exceptionListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $configId);
list($matcher, $listeners, $exceptionListener, $logoutListener) = $this->createFirewall($container, $name, $firewall, $authenticationProviders, $providerIds, $configId);

$contextId = 'security.firewall.map.context.'.$name;
$context = $container->setDefinition($contextId, new ChildDefinition('security.firewall.context'));
$context
->replaceArgument(0, new IteratorArgument($listeners))
->replaceArgument(1, $exceptionListener)
->replaceArgument(2, new Reference($configId))
->replaceArgument(2, $logoutListener)
->replaceArgument(3, new Reference($configId))
;

$contextRefs[$contextId] = new Reference($contextId);
Expand Down Expand Up @@ -237,7 +238,7 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a

// Security disabled?
if (false === $firewall['security']) {
return array($matcher, array(), null);
return array($matcher, array(), null, null);
}

$config->replaceArgument(4, $firewall['stateless']);
Expand Down Expand Up @@ -276,16 +277,15 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
$config->replaceArgument(6, $contextKey);

// Logout listener
$logoutListenerId = null;
if (isset($firewall['logout'])) {
$listenerKeys[] = 'logout';
$listenerId = 'security.logout_listener.'.$id;
$listener = $container->setDefinition($listenerId, new ChildDefinition('security.logout_listener'));
$listener->replaceArgument(3, array(
$logoutListenerId = 'security.logout_listener.'.$id;
$logoutListener = $container->setDefinition($logoutListenerId, new ChildDefinition('security.logout_listener'));
$logoutListener->replaceArgument(3, array(
'csrf_parameter' => $firewall['logout']['csrf_parameter'],
'csrf_token_id' => $firewall['logout']['csrf_token_id'],
'logout_path' => $firewall['logout']['path'],
));
$listeners[] = new Reference($listenerId);

// add logout success handler
if (isset($firewall['logout']['success_handler'])) {
Expand All @@ -295,16 +295,16 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
$logoutSuccessHandler = $container->setDefinition($logoutSuccessHandlerId, new ChildDefinition('security.logout.success_handler'));
$logoutSuccessHandler->replaceArgument(1, $firewall['logout']['target']);
}
$listener->replaceArgument(2, new Reference($logoutSuccessHandlerId));
$logoutListener->replaceArgument(2, new Reference($logoutSuccessHandlerId));

// add CSRF provider
if (isset($firewall['logout']['csrf_token_generator'])) {
$listener->addArgument(new Reference($firewall['logout']['csrf_token_generator']));
$logoutListener->addArgument(new Reference($firewall['logout']['csrf_token_generator']));
}

// add session logout handler
if (true === $firewall['logout']['invalidate_session'] && false === $firewall['stateless']) {
$listener->addMethodCall('addHandler', array(new Reference('security.logout.handler.session')));
$logoutListener->addMethodCall('addHandler', array(new Reference('security.logout.handler.session')));
}

// add cookie logout handler
Expand All @@ -313,12 +313,12 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
$cookieHandler = $container->setDefinition($cookieHandlerId, new ChildDefinition('security.logout.handler.cookie_clearing'));
$cookieHandler->addArgument($firewall['logout']['delete_cookies']);

$listener->addMethodCall('addHandler', array(new Reference($cookieHandlerId)));
$logoutListener->addMethodCall('addHandler', array(new Reference($cookieHandlerId)));
}

// add custom handlers
foreach ($firewall['logout']['handlers'] as $handlerId) {
$listener->addMethodCall('addHandler', array(new Reference($handlerId)));
$logoutListener->addMethodCall('addHandler', array(new Reference($handlerId)));
}

// register with LogoutUrlGenerator
Expand Down Expand Up @@ -378,7 +378,7 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
$config->replaceArgument(10, $listenerKeys);
$config->replaceArgument(11, isset($firewall['switch_user']) ? $firewall['switch_user'] : null);

return array($matcher, $listeners, $exceptionListener);
return array($matcher, $listeners, $exceptionListener, null !== $logoutListenerId ? new Reference($logoutListenerId) : null);
}

private function createContextListener($container, $contextKey)
Expand Down
Expand Up @@ -138,6 +138,7 @@
<service id="security.firewall.context" class="Symfony\Bundle\SecurityBundle\Security\FirewallContext" abstract="true">
<argument type="collection" />
<argument type="service" id="security.exception_listener" />
<argument /> <!-- LogoutListener -->
<argument /> <!-- FirewallConfig -->
</service>

Expand Down
21 changes: 19 additions & 2 deletions src/Symfony/Bundle/SecurityBundle/Security/FirewallContext.php
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Bundle\SecurityBundle\Security;

use Symfony\Component\Security\Http\Firewall\ExceptionListener;
use Symfony\Component\Security\Http\Firewall\LogoutListener;

/**
* This is a wrapper around the actual firewall configuration which allows us
Expand All @@ -23,13 +24,24 @@ class FirewallContext
{
private $listeners;
private $exceptionListener;
private $logoutListener;
private $config;

public function __construct(iterable $listeners, ExceptionListener $exceptionListener = null, FirewallConfig $config = null)
/**
* @param LogoutListener|null $logoutListener
*/
public function __construct(iterable $listeners, ExceptionListener $exceptionListener = null, $logoutListener = null, FirewallConfig $config = null)
{
$this->listeners = $listeners;
$this->exceptionListener = $exceptionListener;
$this->config = $config;
if ($logoutListener instanceof FirewallConfig) {
$this->config = $logoutListener;
} elseif (null === $logoutListener || $logoutListener instanceof LogoutListener) {
$this->logoutListener = $logoutListener;
$this->config = $config;
} else {
throw new \InvalidArgumentException(sprintf('Argument 3 passed to %s() must be instance of %s or null, %s given.', __METHOD__, LogoutListener::class, is_object($logoutListener) ? get_class($logoutListener) : gettype($logoutListener)));
}
}

public function getConfig()
Expand All @@ -46,4 +58,9 @@ public function getExceptionListener()
{
return $this->exceptionListener;
}

public function getLogoutListener()
{
return $this->logoutListener;
}
}
4 changes: 2 additions & 2 deletions src/Symfony/Bundle/SecurityBundle/Security/FirewallMap.php
Expand Up @@ -40,10 +40,10 @@ public function getListeners(Request $request)
$context = $this->getFirewallContext($request);

if (null === $context) {
return array(array(), null);
return array(array(), null, null);
}

return array($context->getListeners(), $context->getExceptionListener());
return array($context->getListeners(), $context->getExceptionListener(), $context->getLogoutListener());
}

/**
Expand Down
Expand Up @@ -71,7 +71,7 @@ public function testFirewalls()
$arguments = $contextDef->getArguments();
$listeners[] = array_map('strval', $arguments['index_0']->getValues());

$configDef = $container->getDefinition((string) $arguments['index_2']);
$configDef = $container->getDefinition((string) $arguments['index_3']);
$configs[] = array_values($configDef->getArguments());
}

Expand Down Expand Up @@ -99,7 +99,6 @@ public function testFirewalls()
null,
null,
array(
'logout',
'switch_user',
'x509',
'remote_user',
Expand Down Expand Up @@ -171,7 +170,6 @@ public function testFirewalls()
array(),
array(
'security.channel_listener',
'security.logout_listener.secure',
'security.authentication.listener.x509.secure',
'security.authentication.listener.remote_user.secure',
'security.authentication.listener.form.secure',
Expand Down
34 changes: 34 additions & 0 deletions src/Symfony/Bundle/SecurityBundle/Tests/Functional/LogoutTest.php
@@ -0,0 +1,34 @@
<?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\Bundle\SecurityBundle\Tests\Functional;

class LogoutTest extends WebTestCase
{
public function testSessionLessRememberMeLogout()
{
$client = $this->createClient(array('test_case' => 'RememberMeLogout', 'root_config' => 'config.yml'));

$client->request('POST', '/login', array(
'_username' => 'johannes',
'_password' => 'test',
));

$cookieJar = $client->getCookieJar();
$cookieJar->expire(session_name());

$this->assertNotNull($cookieJar->get('REMEMBERME'));

$client->request('GET', '/logout');

$this->assertNull($cookieJar->get('REMEMBERME'));
}
}
@@ -0,0 +1,18 @@
<?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.
*/

use Symfony\Bundle\SecurityBundle\SecurityBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;

return array(
new FrameworkBundle(),
new SecurityBundle(),
);
@@ -0,0 +1,25 @@
imports:
- { resource: ./../config/framework.yml }

security:
encoders:
Symfony\Component\Security\Core\User\User: plaintext

providers:
in_memory:
memory:
users:
johannes: { password: test, roles: [ROLE_USER] }

firewalls:
default:
form_login:
check_path: login
remember_me: true
require_previous_session: false
remember_me:
always_remember_me: true
secret: key
logout: ~
anonymous: ~
stateless: true
@@ -0,0 +1,5 @@
login:
path: /login

logout:
path: /logout
Expand Up @@ -16,24 +16,27 @@
use Symfony\Bundle\SecurityBundle\Security\FirewallContext;
use Symfony\Component\Security\Http\Firewall\ExceptionListener;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
use Symfony\Component\Security\Http\Firewall\LogoutListener;

class FirewallContextTest extends TestCase
{
public function testGetters()
{
$config = new FirewallConfig('main', 'user_checker', 'request_matcher');
$exceptionListener = $this->getExceptionListenerMock();
$logoutListener = $this->getLogoutListenerMock();
$listeners = array(
$this
->getMockBuilder(ListenerInterface::class)
->disableOriginalConstructor()
->getMock(),
);

$context = new FirewallContext($listeners, $exceptionListener, $config);
$context = new FirewallContext($listeners, $exceptionListener, $logoutListener, $config);

$this->assertEquals($listeners, $context->getListeners());
$this->assertEquals($exceptionListener, $context->getExceptionListener());
$this->assertEquals($logoutListener, $context->getLogoutListener());
$this->assertEquals($config, $context->getConfig());
}

Expand All @@ -44,4 +47,12 @@ private function getExceptionListenerMock()
->disableOriginalConstructor()
->getMock();
}

private function getLogoutListenerMock()
{
return $this
->getMockBuilder(LogoutListener::class)
->disableOriginalConstructor()
->getMock();
}
}
Expand Up @@ -20,6 +20,7 @@
use Symfony\Component\HttpFoundation\RequestMatcherInterface;
use Symfony\Component\Security\Http\Firewall\ExceptionListener;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
use Symfony\Component\Security\Http\Firewall\LogoutListener;

class FirewallMapTest extends TestCase
{
Expand All @@ -35,7 +36,7 @@ public function testGetListenersWithEmptyMap()

$firewallMap = new FirewallMap($container, $map);

$this->assertEquals(array(array(), null), $firewallMap->getListeners($request));
$this->assertEquals(array(array(), null, null), $firewallMap->getListeners($request));
$this->assertNull($firewallMap->getFirewallConfig($request));
$this->assertFalse($request->attributes->has(self::ATTRIBUTE_FIREWALL_CONTEXT));
}
Expand All @@ -51,7 +52,7 @@ public function testGetListenersWithInvalidParameter()

$firewallMap = new FirewallMap($container, $map);

$this->assertEquals(array(array(), null), $firewallMap->getListeners($request));
$this->assertEquals(array(array(), null, null), $firewallMap->getListeners($request));
$this->assertNull($firewallMap->getFirewallConfig($request));
$this->assertFalse($request->attributes->has(self::ATTRIBUTE_FIREWALL_CONTEXT));
}
Expand All @@ -71,6 +72,9 @@ public function testGetListeners()
$exceptionListener = $this->getMockBuilder(ExceptionListener::class)->disableOriginalConstructor()->getMock();
$firewallContext->expects($this->once())->method('getExceptionListener')->willReturn($exceptionListener);

$logoutListener = $this->getMockBuilder(LogoutListener::class)->disableOriginalConstructor()->getMock();
$firewallContext->expects($this->once())->method('getLogoutListener')->willReturn($logoutListener);

$matcher = $this->getMockBuilder(RequestMatcherInterface::class)->getMock();
$matcher->expects($this->once())
->method('matches')
Expand All @@ -82,7 +86,7 @@ public function testGetListeners()

$firewallMap = new FirewallMap($container, array('security.firewall.map.context.foo' => $matcher));

$this->assertEquals(array(array($listener), $exceptionListener), $firewallMap->getListeners($request));
$this->assertEquals(array(array($listener), $exceptionListener, $logoutListener), $firewallMap->getListeners($request));
$this->assertEquals($firewallConfig, $firewallMap->getFirewallConfig($request));
$this->assertEquals('security.firewall.map.context.foo', $request->attributes->get(self::ATTRIBUTE_FIREWALL_CONTEXT));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Bundle/SecurityBundle/composer.json
Expand Up @@ -18,7 +18,7 @@
"require": {
"php": "^7.1.3",
"ext-xml": "*",
"symfony/security": "~3.4|~4.0",
"symfony/security": "~3.4.10|^4.0.10",
"symfony/dependency-injection": "^3.4.3|^4.0.3",
"symfony/http-kernel": "~3.4|~4.0"
},
Expand Down
Expand Up @@ -7,10 +7,8 @@
'default': '#999',
'section': '#444',
'event_listener': '#00B8F5',
'event_listener_loading': '#00B8F5',
'template': '#66CC00',
'doctrine': '#FF6633',
'propel': '#FF6633',
} %}
{% endif %}

Expand Down
9 changes: 6 additions & 3 deletions src/Symfony/Component/Cache/Traits/RedisTrait.php
Expand Up @@ -126,9 +126,12 @@ public static function createConnection($dsn, array $options = array())
throw new InvalidArgumentException(sprintf('Redis connection failed (%s): %s', $e->getMessage(), $dsn));
}

if (@!$redis->isConnected()) {
$e = ($e = error_get_last()) && preg_match('/^Redis::p?connect\(\): (.*)/', $e['message'], $e) ? sprintf(' (%s)', $e[1]) : '';
throw new InvalidArgumentException(sprintf('Redis connection failed%s: %s', $e, $dsn));
set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
$isConnected = $redis->isConnected();
restore_error_handler();
if (!$isConnected) {
$error = preg_match('/^Redis::p?connect\(\): (.*)/', $error, $error) ? sprintf(' (%s)', $error[1]) : '';
throw new InvalidArgumentException(sprintf('Redis connection failed%s: %s', $error, $dsn));
}

if ((null !== $auth && !$redis->auth($auth))
Expand Down

0 comments on commit 8c430fb

Please sign in to comment.