Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6f48ec5

Browse files
committed
Merge branch '2.7' into 2.8
* 2.7: [TwigBundle] Fix Twig cache is not properly warmed [Security] Use SessionAuthenticationStrategy on RememberMe login
2 parents 72c6c61 + 6e6a0ba commit 6f48ec5

File tree

9 files changed

+216
-16
lines changed

9 files changed

+216
-16
lines changed

src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
<argument type="service" id="logger" on-invalid="null" />
2626
<argument type="service" id="event_dispatcher" on-invalid="null"/>
2727
<argument /> <!-- Catch exception flag set in RememberMeFactory -->
28+
<argument type="service" id="security.authentication.session_strategy" />
2829
</service>
2930

3031
<service id="security.authentication.provider.rememberme" class="%security.authentication.provider.rememberme.class%" abstract="true" public="false">

src/Symfony/Bundle/TwigBundle/CacheWarmer/TemplateCacheCacheWarmer.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,13 @@ class TemplateCacheCacheWarmer implements CacheWarmerInterface
3838
* @param TemplateFinderInterface $finder The template paths cache warmer
3939
* @param array $paths Additional twig paths to warm
4040
*/
41-
public function __construct(ContainerInterface $container, TemplateFinderInterface $finder, array $paths = array())
41+
public function __construct(ContainerInterface $container, TemplateFinderInterface $finder = null, array $paths = array())
4242
{
4343
// We don't inject the Twig environment directly as it depends on the
4444
// template locator (via the loader) which might be a cached one.
4545
// The cached template locator is available once the TemplatePathsCacheWarmer
46-
// has been warmed up
46+
// has been warmed up.
47+
// But it can also be null if templating has been disabled.
4748
$this->container = $container;
4849
$this->finder = $finder;
4950
$this->paths = $paths;
@@ -56,6 +57,10 @@ public function __construct(ContainerInterface $container, TemplateFinderInterfa
5657
*/
5758
public function warmUp($cacheDir)
5859
{
60+
if (null === $this->finder) {
61+
return;
62+
}
63+
5964
$twig = $this->container->get('twig');
6065

6166
$templates = $this->finder->findAllTemplates();

src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,7 @@ public function process(ContainerBuilder $container)
6868
$container->getDefinition('twig.extension.debug')->addTag('twig.extension');
6969
}
7070

71-
if ($container->has('templating')) {
72-
$container->getDefinition('twig.cache_warmer')->addTag('kernel.cache_warmer');
73-
} else {
71+
if (!$container->has('templating')) {
7472
$loader = $container->getDefinition('twig.loader.native_filesystem');
7573
$loader->addTag('twig.loader');
7674
$loader->setMethodCalls($container->getDefinition('twig.loader.filesystem')->getMethodCalls());

src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@
4646
</service>
4747

4848
<service id="twig.cache_warmer" class="%twig.cache_warmer.class%" public="false">
49+
<tag name="kernel.cache_warmer" />
4950
<argument type="service" id="service_container" />
50-
<argument type="service" id="templating.finder" />
51+
<argument type="service" id="templating.finder" on-invalid="ignore" />
5152
<argument type="collection" /> <!-- Twig paths -->
5253
</service>
5354

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\TwigBundle\Tests;
13+
14+
use Symfony\Component\HttpKernel\Kernel;
15+
use Symfony\Component\Config\Loader\LoaderInterface;
16+
use Symfony\Component\Filesystem\Filesystem;
17+
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
18+
use Symfony\Bundle\TwigBundle\TwigBundle;
19+
20+
class NewCacheWamingTest extends \PHPUnit_Framework_TestCase
21+
{
22+
public function testCacheIsProperlyWarmedWhenTemplatingIsAvailable()
23+
{
24+
$kernel = new CacheWarmingKernel(true);
25+
$kernel->boot();
26+
27+
$warmer = $kernel->getContainer()->get('cache_warmer');
28+
$warmer->enableOptionalWarmers();
29+
$warmer->warmUp($kernel->getCacheDir());
30+
31+
$this->assertTrue(file_exists($kernel->getCacheDir().'/twig'));
32+
}
33+
34+
public function testCacheIsNotWarmedWhenTemplatingIsDisabled()
35+
{
36+
$kernel = new CacheWarmingKernel(false);
37+
$kernel->boot();
38+
39+
$warmer = $kernel->getContainer()->get('cache_warmer');
40+
$warmer->enableOptionalWarmers();
41+
$warmer->warmUp($kernel->getCacheDir());
42+
43+
$this->assertFalse(file_exists($kernel->getCacheDir().'/twig'));
44+
}
45+
46+
protected function setUp()
47+
{
48+
$this->deleteTempDir();
49+
}
50+
51+
protected function tearDown()
52+
{
53+
$this->deleteTempDir();
54+
}
55+
56+
private function deleteTempDir()
57+
{
58+
if (!file_exists($dir = sys_get_temp_dir().'/'.Kernel::VERSION.'/CacheWarmingKernel')) {
59+
return;
60+
}
61+
62+
$fs = new Filesystem();
63+
$fs->remove($dir);
64+
}
65+
}
66+
67+
class CacheWarmingKernel extends Kernel
68+
{
69+
private $withTemplating;
70+
71+
public function __construct($withTemplating)
72+
{
73+
$this->withTemplating = $withTemplating;
74+
75+
parent::__construct('dev', true);
76+
}
77+
78+
public function getName()
79+
{
80+
return 'CacheWarming';
81+
}
82+
83+
public function registerBundles()
84+
{
85+
return array(new FrameworkBundle(), new TwigBundle());
86+
}
87+
88+
public function registerContainerConfiguration(LoaderInterface $loader)
89+
{
90+
$loader->load(function ($container) {
91+
$container->loadFromExtension('framework', array(
92+
'secret' => '$ecret',
93+
));
94+
});
95+
96+
if ($this->withTemplating) {
97+
$loader->load(function ($container) {
98+
$container->loadFromExtension('framework', array(
99+
'secret' => '$ecret',
100+
'templating' => array('engines' => array('twig')),
101+
'router' => array('resource' => '%kernel.root_dir%/Resources/config/empty_routing.yml'),
102+
));
103+
});
104+
}
105+
}
106+
107+
public function getCacheDir()
108+
{
109+
return sys_get_temp_dir().'/'.Kernel::VERSION.'/CacheWarmingKernel/cache';
110+
}
111+
112+
public function getLogDir()
113+
{
114+
return sys_get_temp_dir().'/'.Kernel::VERSION.'/CacheWarmingKernel/logs';
115+
}
116+
}

src/Symfony/Bundle/TwigBundle/Tests/Functional/Resources/config/empty_routing.yml

Whitespace-only changes.

src/Symfony/Bundle/TwigBundle/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"symfony/dependency-injection": "~2.6,>=2.6.6|~3.0.0",
2828
"symfony/expression-language": "~2.4|~3.0.0",
2929
"symfony/config": "~2.8|~3.0.0",
30+
"symfony/finder": "~2.0,>=2.0.5",
3031
"symfony/routing": "~2.1|~3.0.0",
3132
"symfony/templating": "~2.1|~3.0.0",
3233
"symfony/yaml": "~2.3|~3.0.0",

src/Symfony/Component/Security/Http/Firewall/RememberMeListener.php

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
2121
use Symfony\Component\Security\Http\SecurityEvents;
2222
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
23+
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface;
2324

2425
/**
2526
* RememberMeListener implements authentication capabilities via a cookie.
@@ -34,25 +35,28 @@ class RememberMeListener implements ListenerInterface
3435
private $logger;
3536
private $dispatcher;
3637
private $catchExceptions = true;
38+
private $sessionStrategy;
3739

3840
/**
3941
* Constructor.
4042
*
41-
* @param TokenStorageInterface $tokenStorage
42-
* @param RememberMeServicesInterface $rememberMeServices
43-
* @param AuthenticationManagerInterface $authenticationManager
44-
* @param LoggerInterface $logger
45-
* @param EventDispatcherInterface $dispatcher
46-
* @param bool $catchExceptions
43+
* @param TokenStorageInterface $tokenStorage
44+
* @param RememberMeServicesInterface $rememberMeServices
45+
* @param AuthenticationManagerInterface $authenticationManager
46+
* @param LoggerInterface $logger
47+
* @param EventDispatcherInterface $dispatcher
48+
* @param bool $catchExceptions
49+
* @param SessionAuthenticationStrategyInterface $sessionStrategy
4750
*/
48-
public function __construct(TokenStorageInterface $tokenStorage, RememberMeServicesInterface $rememberMeServices, AuthenticationManagerInterface $authenticationManager, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, $catchExceptions = true)
51+
public function __construct(TokenStorageInterface $tokenStorage, RememberMeServicesInterface $rememberMeServices, AuthenticationManagerInterface $authenticationManager, LoggerInterface $logger = null, EventDispatcherInterface $dispatcher = null, $catchExceptions = true, SessionAuthenticationStrategyInterface $sessionStrategy = null)
4952
{
5053
$this->tokenStorage = $tokenStorage;
5154
$this->rememberMeServices = $rememberMeServices;
5255
$this->authenticationManager = $authenticationManager;
5356
$this->logger = $logger;
5457
$this->dispatcher = $dispatcher;
5558
$this->catchExceptions = $catchExceptions;
59+
$this->sessionStrategy = $sessionStrategy;
5660
}
5761

5862
/**
@@ -73,6 +77,9 @@ public function handle(GetResponseEvent $event)
7377

7478
try {
7579
$token = $this->authenticationManager->authenticate($token);
80+
if (null !== $this->sessionStrategy && $request->hasSession() && $request->getSession()->isStarted()) {
81+
$this->sessionStrategy->onAuthentication($request, $token);
82+
}
7683
$this->tokenStorage->setToken($token);
7784

7885
if (null !== $this->dispatcher) {

src/Symfony/Component/Security/Http/Tests/Firewall/RememberMeListenerTest.php

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,71 @@ public function testOnCoreSecurity()
181181
$listener->handle($event);
182182
}
183183

184+
public function testSessionStrategy()
185+
{
186+
list($listener, $tokenStorage, $service, $manager, , $dispatcher, $sessionStrategy) = $this->getListener(false, true, true);
187+
188+
$tokenStorage
189+
->expects($this->once())
190+
->method('getToken')
191+
->will($this->returnValue(null))
192+
;
193+
194+
$token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
195+
$service
196+
->expects($this->once())
197+
->method('autoLogin')
198+
->will($this->returnValue($token))
199+
;
200+
201+
$tokenStorage
202+
->expects($this->once())
203+
->method('setToken')
204+
->with($this->equalTo($token))
205+
;
206+
207+
$manager
208+
->expects($this->once())
209+
->method('authenticate')
210+
->will($this->returnValue($token))
211+
;
212+
213+
$session = $this->getMock('\Symfony\Component\HttpFoundation\Session\SessionInterface');
214+
$session
215+
->expects($this->once())
216+
->method('isStarted')
217+
->will($this->returnValue(true))
218+
;
219+
220+
$request = $this->getMock('\Symfony\Component\HttpFoundation\Request');
221+
$request
222+
->expects($this->once())
223+
->method('hasSession')
224+
->will($this->returnValue(true))
225+
;
226+
227+
$request
228+
->expects($this->once())
229+
->method('getSession')
230+
->will($this->returnValue($session))
231+
;
232+
233+
$event = $this->getGetResponseEvent();
234+
$event
235+
->expects($this->once())
236+
->method('getRequest')
237+
->will($this->returnValue($request))
238+
;
239+
240+
$sessionStrategy
241+
->expects($this->once())
242+
->method('onAuthentication')
243+
->will($this->returnValue(null))
244+
;
245+
246+
$listener->handle($event);
247+
}
248+
184249
public function testOnCoreSecurityInteractiveLoginEventIsDispatchedIfDispatcherIsPresent()
185250
{
186251
list($listener, $tokenStorage, $service, $manager, , $dispatcher) = $this->getListener(true);
@@ -240,18 +305,19 @@ protected function getFilterResponseEvent()
240305
return $this->getMock('Symfony\Component\HttpKernel\Event\FilterResponseEvent', array(), array(), '', false);
241306
}
242307

243-
protected function getListener($withDispatcher = false, $catchExceptions = true)
308+
protected function getListener($withDispatcher = false, $catchExceptions = true, $withSessionStrategy = false)
244309
{
245310
$listener = new RememberMeListener(
246311
$tokenStorage = $this->getTokenStorage(),
247312
$service = $this->getService(),
248313
$manager = $this->getManager(),
249314
$logger = $this->getLogger(),
250315
$dispatcher = ($withDispatcher ? $this->getDispatcher() : null),
251-
$catchExceptions
316+
$catchExceptions,
317+
$sessionStrategy = ($withSessionStrategy ? $this->getSessionStrategy() : null)
252318
);
253319

254-
return array($listener, $tokenStorage, $service, $manager, $logger, $dispatcher);
320+
return array($listener, $tokenStorage, $service, $manager, $logger, $dispatcher, $sessionStrategy);
255321
}
256322

257323
protected function getLogger()
@@ -278,4 +344,9 @@ protected function getDispatcher()
278344
{
279345
return $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
280346
}
347+
348+
private function getSessionStrategy()
349+
{
350+
return $this->getMock('\Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface');
351+
}
281352
}

0 commit comments

Comments
 (0)