Skip to content

Commit bd233ac

Browse files
committed
Merge pull request #1066 from hyperunknown/csrf-ext-patch-1
Updated DisableCSRFExtension for 2.7+
2 parents 12cc43d + 070f925 commit bd233ac

File tree

5 files changed

+75
-11
lines changed

5 files changed

+75
-11
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the FOSRestBundle package.
5+
*
6+
* (c) FriendsOfSymfony <http://friendsofsymfony.github.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 FOS\RestBundle\DependencyInjection\Compiler;
13+
14+
use Symfony\Component\DependencyInjection\Reference;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
17+
18+
class CsrfExtensionPass implements CompilerPassInterface
19+
{
20+
public function process(ContainerBuilder $container)
21+
{
22+
if($container->hasDefinition('fos_rest.form.extension.csrf_disable')) {
23+
$definition = $container->getDefinition('fos_rest.form.extension.csrf_disable');
24+
25+
if (interface_exists('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')) {
26+
$tokenStorageReference = new Reference('security.token_storage');
27+
$definition->addArgument(new Reference('security.authorization_checker'));
28+
} else {
29+
$tokenStorageReference = new Reference('security.context');
30+
}
31+
$definition->replaceArgument(0, $tokenStorageReference);
32+
}
33+
}
34+
}

FOSRestBundle.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use FOS\RestBundle\DependencyInjection\Compiler\ExceptionWrapperHandlerPass;
1919
use FOS\RestBundle\DependencyInjection\Compiler\FormatListenerRulesPass;
2020
use FOS\RestBundle\DependencyInjection\Compiler\TwigExceptionPass;
21+
use FOS\RestBundle\DependencyInjection\Compiler\CsrfExtensionPass;
2122

2223
/**
2324
* @author Lukas Kahwe Smith <[email protected]>
@@ -35,5 +36,6 @@ public function build(ContainerBuilder $container)
3536
$container->addCompilerPass(new FormatListenerRulesPass());
3637
$container->addCompilerPass(new TwigExceptionPass());
3738
$container->addCompilerPass(new ExceptionWrapperHandlerPass());
39+
$container->addCompilerPass(new CsrfExtensionPass());
3840
}
3941
}

Form/Extension/DisableCSRFExtension.php

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@
1212
namespace FOS\RestBundle\Form\Extension;
1313

1414
use Symfony\Component\Form\AbstractTypeExtension;
15+
use Symfony\Component\OptionsResolver\OptionsResolver;
1516
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
1617
use Symfony\Component\Security\Core\SecurityContextInterface;
18+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
19+
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
1720

1821
/**
1922
* Class DisableCSRFExtension
@@ -22,30 +25,55 @@
2225
*/
2326
class DisableCSRFExtension extends AbstractTypeExtension
2427
{
25-
private $securityContext;
28+
/**
29+
* @var SecurityContextInterface|TokenStorageInterface
30+
*/
31+
private $tokenStorage;
2632
private $role;
33+
private $authorizationChecker;
2734

28-
public function __construct(SecurityContextInterface $securityContext, $role)
35+
public function __construct($tokenStorage, $role, $authorizationChecker = null)
2936
{
30-
$this->securityContext = $securityContext;
37+
$this->tokenStorage = $tokenStorage;
3138
$this->role = $role;
39+
$this->authorizationChecker = $authorizationChecker;
40+
41+
if (!$tokenStorage instanceof TokenStorageInterface && !$tokenStorage instanceof SecurityContextInterface) {
42+
throw new \InvalidArgumentException('Argument 1 should be an instance of Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface or Symfony\Component\Security\Core\SecurityContextInterface');
43+
}
3244
}
3345

34-
public function setDefaultOptions(OptionsResolverInterface $resolver)
46+
public function configureOptions(OptionsResolver $resolver)
3547
{
36-
if (!$this->securityContext->getToken()) {
37-
return;
38-
}
48+
if ($this->authorizationChecker instanceof AuthorizationCheckerInterface) {
49+
if (!$this->tokenStorage->getToken()) {
50+
return;
51+
}
52+
53+
if (!$this->authorizationChecker->isGranted($this->role)) {
54+
return;
55+
}
56+
} else {
57+
if (!$this->tokenStorage->getToken()) {
58+
return;
59+
}
3960

40-
if (!$this->securityContext->isGranted($this->role)) {
41-
return;
61+
if (!$this->tokenStorage->isGranted($this->role)) {
62+
return;
63+
}
4264
}
4365

4466
$resolver->setDefaults(array(
4567
'csrf_protection' => false,
4668
));
4769
}
4870

71+
// BC for < 2.7
72+
public function setDefaultOptions(OptionsResolverInterface $resolver)
73+
{
74+
$this->configureOptions($resolver);
75+
}
76+
4977
public function getExtendedType()
5078
{
5179
return 'form';

Resources/config/forms.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<services>
1414
<service id="fos_rest.form.extension.csrf_disable" class="%fos_rest.form.extension.csrf_disable.class%">
1515
<tag name="form.type_extension" alias="form" />
16-
<argument type="service" id="security.context" />
16+
<argument /> <!-- security.token_storage or security.context for Symfony < 2.6 -->
1717
<argument>%fos_rest.disable_csrf_role%</argument>
1818
</service>
1919
</services>

Tests/FOSRestBundleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function testBuild()
2525
$container = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerBuilder')
2626
->setMethods(array('addCompilerPass'))
2727
->getMock();
28-
$container->expects($this->exactly(5))
28+
$container->expects($this->exactly(6))
2929
->method('addCompilerPass')
3030
->with($this->isInstanceOf('\Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface'));
3131

0 commit comments

Comments
 (0)