8000 [SecurityBundle] decouple the logout PHP helper and Twig extension · symfony/symfony@820b726 · GitHub
[go: up one dir, main page]

Skip to content

Commit 820b726

Browse files
committed
[SecurityBundle] decouple the logout PHP helper and Twig extension
1 parent 497fdd4 commit 820b726

File tree

10 files changed

+242
-88
lines changed

10 files changed

+242
-88
lines changed

src/Symfony/Bridge/Twig/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
2.7.0
55
-----
66

7+
* added LogoutUrlExtension (provides `logout_url` and `logout_path`)
78
* added an HttpFoundation extension (provides the `absolute_url` and the `relative_path` functions)
89

910
2.5.0
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\Bridge\Twig\Extension;
13+
14+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
15+
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
16+
17+
/**
18+
* LogoutUrlHelper provides generator functions for the logout URL to Twig.
19+
*
20+
* @author Jeremy Mikola <jmikola@gmail.com>
21+
*/
22+
class LogoutUrlExtension extends \Twig_Extension
23+
{
24+
private $generator;
25+
26+
public function __construct(LogoutUrlGenerator $generator)
27+
{
28+
$this->generator = $generator;
29+
}
30+
31+
/**
32+
* {@inheritdoc}
33+
*/
34+
public function getFunctions()
35+
{
36+
return array(
37+
new \Twig_SimpleFunction('logout_url', array($this, 'getLogoutUrl')),
38+
new \Twig_SimpleFunction('logout_path', array($this, 'getLogoutPath')),
39+
);
40+
}
41+
42+
/**
43+
* Generates the relative logout URL for the firewall.
44+
*
45+
* @param string|null $key The firewall key or null to use the current firewall key
46+
*
47+
* @return string The relative logout URL
48+
*/
49+
public function getLogoutPath($key = null)
50+
{
51+
return $this->generator->getLogoutPath($key, UrlGeneratorInterface::ABSOLUTE_PATH);
52+
}
53+
54+
/**
55+
* Generates the absolute logout URL for the firewall.
56+
*
57+
* @param string|null $key The firewall key or null to use the current firewall key
58+
*
59+
* @return string The absolute logout URL
60+
*/
61+
public function getLogoutUrl($key = null< F438 /span>)
62+
{
63+
return $this->generator->getLogoutUrl($key, UrlGeneratorInterface::ABSOLUTE_URL);
64+
}
65+
66+
/**
67+
* {@inheritdoc}
68+
*/
69+
public function getName()
70+
{
71+
return 'logout_url';
72+
}
73+
}

src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,9 +337,9 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
337337
$listener->addMethodCall('addHandler', array(new Reference($handlerId)));
338338
}
339339

340-
// register with LogoutUrlHelper
340+
// register with LogoutGenerator
341341
$container
342-
->getDefinition('templating.helper.logout_url')
342+
->getDefinition('security.logout_generator')
343343
->addMethodCall('registerListener', array(
344344
$id,
345345
$firewall['logout']['path'],

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@
152152
<argument type="service" id="security.exception_listener" />
153153
</service>
154154

155+
<service id="security.logout_generator" class="Symfony\Component\Security\Http\Logout\LogoutUrlGenerator" public="false">
156+
<argument type="service" id="request_stack" on-invalid="null" />
157+
<argument type="service" id="router" on-invalid="null" />
158+
<argument type="service" id="security.token_storage" on-invalid="null" />
159+
</service>
160+
155161
<!-- Provisioning -->
156162
<service id="security.user.provider.in_memory" class="%security.user.provider.in_memory.class%" abstract="true" public="false" />
157163
<service id="security.user.provider.in_memory.user" class="%security.user.provider.in_memory.user.class%" abstract="true" public="false" />

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
<services>
1313
<service id="templating.helper.logout_url" class="%templating.helper.logout_url.class%">
1414
<tag name="templating.helper" alias="logout_url" />
15-
<argument type="service" id="request_stack" />
16-
<argument type="service" id="router" />
17-
<argument type="service" id="security.token_storage" />
15+
<argument type="service" id="security.logout_generator" />
1816
</service>
1917

2018
<service id="templating.helper.security" class="%templating.helper.security.class%">

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
66

77
<parameters>
8-
<parameter key="twig.extension.logout_url.class">Symfony\Bundle\SecurityBundle\Twig\Extension\LogoutUrlExtension</parameter>
8+
<parameter key="twig.extension.logout_url.class">Symfony\Bridge\Twig\Extension\LogoutUrlExtension</parameter>
99
<parameter key="twig.extension.security.class">Symfony\Bridge\Twig\Extension\SecurityExtension</parameter>
1010
</parameters>
1111

1212
<services>
1313
<service id="twig.extension.logout_url" class="%twig.extension.logout_url.class%" public="false">
1414
<tag name="twig.extension" />
15-
<argument type="service" id="templating.helper.logout_url" />
15+
<argument type="service" id="security.logout_generator" />
1616
</service>
1717

1818
<service id="twig.extension.security" class="%twig.extension.security.class%" public="false">

src/Symfony/Bundle/SecurityBundle/Templating/Helper/LogoutUrlHelper.php

Lines changed: 11 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
1717
use Symfony\Component\HttpFoundation\RequestStack;
1818
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
19+
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
1920
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
2021
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
22+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
2123
use Symfony\Component\Templating\Helper\Helper;
2224

2325
/**
@@ -35,45 +37,21 @@ class LogoutUrlHelper extends Helper
3537
/**
3638
* Constructor.
3739
*
38-
* @param ContainerInterface|RequestStack $requestStack A ContainerInterface instance or RequestStack
39-
* @param UrlGeneratorInterface $router The router service
40-
* @param TokenStorageInterface|null $tokenStorage The token storage service
40+
* @param ContainerInterface|LogoutUrlGenerator $generator A ContainerInterface or LogoutUrlGenerator instance
41+
* @param UrlGeneratorInterface|null $router The router service
42+
* @param TokenStorageInterface|null $tokenStorage The token storage service
4143
*
4244
* @deprecated Passing a ContainerInterface as a first argument is deprecated since 2.7 and will be removed in 3.0.
45+
* @deprecated Passing a second and third argument is deprecated since 2.7 and will be removed in 3.0.
4346
*/
44-
public function __construct($requestStack, UrlGeneratorInterface $router, TokenStorageInterface $tokenStorage = null)
47+
public function __construct($generator, UrlGeneratorInterface $router = null, TokenStorageInterface $tokenStorage = null)
4548
{
4649
if ($requestStack instanceof ContainerInterface) {
47-
$this->requestStack = $requestStack->get('request_stack');
50+
$this->generator = $container->get('security.logout_generator');
4851
trigger_error('The '.__CLASS__.' constructor will require a RequestStack instead of a ContainerInterface instance in 3.0.', E_USER_DEPRECATED);
49-
} elseif ($requestStack instanceof RequestStack) {
50-
$this->requestStack = $requestStack;
5152
} else {
52-
throw new \InvalidArgumentException(sprintf('%s takes either a RequestStack or a ContainerInterface object as its first argument.', __METHOD__));
53-
}
54-
55-
$this->router = $router;
56-
$this->tokenStorage = $tokenStorage;
57-
}
58-
59-
/**
60-
* Registers a firewall's LogoutListener, allowing its URL to be generated.
61-
*
62-
* @param string $key The firewall key
63-
* @param string $logoutPath The path that starts the logout process
64-
* @param string $csrfTokenId The ID of the CSRF token
65-
* @param string $csrfParameter The CSRF token parameter name
66-
* @param CsrfTokenManagerInterface $csrfTokenManager A CsrfTokenManagerInterface instance
67-
*/
68-
public function registerListener($key, $logoutPath, $csrfTokenId, $csrfParameter, $csrfTokenManager = null)
69-
{
70-
if ($csrfTokenManager instanceof CsrfProviderInterface) {
71-
$csrfTokenManager = new CsrfProviderAdapter($csrfTokenManager);
72-
} elseif (null !== $csrfTokenManager && !$csrfTokenManager instanceof CsrfTokenManagerInterface) {
73-
throw new \InvalidArgumentException('The CSRF token manager should be an instance of CsrfProviderInterface or CsrfTokenManagerInterface.');
53+
$this->generator = $generator;
7454
}
75-
76-
$this->listeners[$key] = array($logoutPath, $csrfTokenId, $csrfParameter, $csrfTokenManager);
7755
}
7856

7957
/**
@@ -85,7 +63,7 @@ public function registerListener($key, $logoutPath, $csrfTokenId, $csrfParameter
8563
*/
8664
public function getLogoutPath($key)
8765
{
88-
return $this->generateLogoutUrl($key, UrlGeneratorInterface::ABSOLUTE_PATH);
66+
return $this->generator->getLogoutPath($key, UrlGeneratorInterface::ABSOLUTE_PATH);
8967
}
9068

9169
/**
@@ -97,54 +75,7 @@ public function getLogoutPath($key)
9775
*/
9876
public function getLogoutUrl($key)
9977
{
100-
return $this->generateLogoutUrl($key, UrlGeneratorInterface::ABSOLUTE_URL);
101-
}
102-
103-
/**
104-
* Generates the logout URL for the firewall.
105-
*
106-
* @param string|null $key The firewall key or null to use the current firewall key
107-
* @param bool|string $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
108-
*
109-
* @return string The logout URL
110-
*
111-
* @throws \InvalidArgumentException if no LogoutListener is registered for the key or the key could not be found automatically.
112-
*/
113-
private function generateLogoutUrl($key, $referenceType)
114-
{
115-
// Fetch the current provider key from token, if possible
116-
if (null === $key && null !== $this->tokenStorage) {
117-
$token = $this->tokenStorage->getToken();
118-
if (null !== $token && method_exists($token, 'getProviderKey')) {
119-
$key = $token->getProviderKey();
120-
}
121-
}
122-
123-
if (null === $key) {
124-
throw new \InvalidArgumentException('Unable to find the current firewall LogoutListener, please provide the provider key manually.');
125-
}
126-
127-
if (!array_key_exists($key, $this->listeners)) {
128-
throw new \InvalidArgumentException(sprintf('No LogoutListener found for firewall key "%s".', $key));
129-
}
130-
131-
list($logoutPath, $csrfTokenId, $csrfParameter, $csrfTokenManager) = $this->listeners[$key];
132-
133-
$parameters = null !== $csrfTokenManager ? array($csrfParameter => (string) $csrfTokenManager->getToken($csrfTokenId)) : array();
134-
135-
if ('/' === $logoutPath[0]) {
136-
$request = $this->requestStack->getCurrentRequest();
137-
138-
$url = UrlGeneratorInterface::ABSOLUTE_URL === $referenceType ? $request->getUriForPath($logoutPath) : $request->getBasePath().$logoutPath;
139-
140-
if (!empty($parameters)) {
141-
$url .= '?'.http_build_query($parameters);
142-
}
143-
} else {
144-
$url = $this->router->generate($logoutPath, $parameters, $referenceType);
145-
}
146-
147-
return $url;
78+
return $this->generator->getLogoutUrl($key, UrlGeneratorInterface::ABSOLUTE_URL);
14879
}
14980

15081
/**

src/Symfony/Bundle/SecurityBundle/Twig/Extension/LogoutUrlExtension.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@
1111

1212
namespace Symfony\Bundle\SecurityBundle\Twig\Extension;
1313

14+
trigger_error('The '.__NAMESPACE__.'\LogoutUrlExtension class is deprecated since version 2.5 and will be removed in 3.0. Use Symfony\Bridge\Twig\Extension\LogoutUrlExtension instead.', E_USER_DEPRECATED);
15+
1416
use Symfony\Bundle\SecurityBundle\Templating\Helper\LogoutUrlHelper;
1517

1618
/**
1719
* LogoutUrlHelper provides generator functions for the logout URL to Twig.
1820
*
1921
* @author Jeremy Mikola <jmikola@gmail.com>
22+
*
23+
* @deprecated since version 2.7, to be removed in 3.0. Use Symfony\Bridge\Twig\Extension\LogoutUrlExtension instead.
2024
*/
2125
class LogoutUrlExtension extends \Twig_Extension
2226
{

src/Symfony/Component/Security/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ CHANGELOG
44
2.7.0
55
-----
66

7-
* Added the triggering of the `Symfony\Component\Security\Http\SecurityEvents::INTERACTIVE_LOGIN` in `Symfony\Component\Security\Http\Firewall\SimplePreAuthenticationListener`
7+
* added LogoutUrlGenerator
8+
* added the triggering of the `Symfony\Component\Security\Http\SecurityEvents::INTERACTIVE_LOGIN` in `Symfony\Component\Security\Http\Firewall\SimplePreAuthenticationListener`
89

910
2.6.0
1011
-----

0 commit comments

Comments
 (0)
0