Skip to content

Commit

Permalink
Merge pull request #1066 from hyperunknown/csrf-ext-patch-1
Browse files Browse the repository at this point in the history
Updated DisableCSRFExtension for 2.7+
  • Loading branch information
lsmith77 committed Jun 15, 2015
2 parents 12cc43d + 070f925 commit bd233ac
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 11 deletions.
34 changes: 34 additions & 0 deletions DependencyInjection/Compiler/CsrfExtensionPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

/*
* This file is part of the FOSRestBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace FOS\RestBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;

class CsrfExtensionPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if($container->hasDefinition('fos_rest.form.extension.csrf_disable')) {
$definition = $container->getDefinition('fos_rest.form.extension.csrf_disable');

if (interface_exists('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface')) {
$tokenStorageReference = new Reference('security.token_storage');
$definition->addArgument(new Reference('security.authorization_checker'));
} else {
$tokenStorageReference = new Reference('security.context');
}
$definition->replaceArgument(0, $tokenStorageReference);
}
}
}
2 changes: 2 additions & 0 deletions FOSRestBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use FOS\RestBundle\DependencyInjection\Compiler\ExceptionWrapperHandlerPass;
use FOS\RestBundle\DependencyInjection\Compiler\FormatListenerRulesPass;
use FOS\RestBundle\DependencyInjection\Compiler\TwigExceptionPass;
use FOS\RestBundle\DependencyInjection\Compiler\CsrfExtensionPass;

/**
* @author Lukas Kahwe Smith <[email protected]>
Expand All @@ -35,5 +36,6 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new FormatListenerRulesPass());
$container->addCompilerPass(new TwigExceptionPass());
$container->addCompilerPass(new ExceptionWrapperHandlerPass());
$container->addCompilerPass(new CsrfExtensionPass());
}
}
46 changes: 37 additions & 9 deletions Form/Extension/DisableCSRFExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
namespace FOS\RestBundle\Form\Extension;

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

/**
* Class DisableCSRFExtension
Expand All @@ -22,30 +25,55 @@
*/
class DisableCSRFExtension extends AbstractTypeExtension
{
private $securityContext;
/**
* @var SecurityContextInterface|TokenStorageInterface
*/
private $tokenStorage;
private $role;
private $authorizationChecker;

public function __construct(SecurityContextInterface $securityContext, $role)
public function __construct($tokenStorage, $role, $authorizationChecker = null)
{
$this->securityContext = $securityContext;
$this->tokenStorage = $tokenStorage;
$this->role = $role;
$this->authorizationChecker = $authorizationChecker;

if (!$tokenStorage instanceof TokenStorageInterface && !$tokenStorage instanceof SecurityContextInterface) {
throw new \InvalidArgumentException('Argument 1 should be an instance of Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface or Symfony\Component\Security\Core\SecurityContextInterface');
}
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
public function configureOptions(OptionsResolver $resolver)
{
if (!$this->securityContext->getToken()) {
return;
}
if ($this->authorizationChecker instanceof AuthorizationCheckerInterface) {
if (!$this->tokenStorage->getToken()) {
return;
}

if (!$this->authorizationChecker->isGranted($this->role)) {
return;
}
} else {
if (!$this->tokenStorage->getToken()) {
return;
}

if (!$this->securityContext->isGranted($this->role)) {
return;
if (!$this->tokenStorage->isGranted($this->role)) {
return;
}
}

$resolver->setDefaults(array(
'csrf_protection' => false,
));
}

// BC for < 2.7
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$this->configureOptions($resolver);
}

public function getExtendedType()
{
return 'form';
Expand Down
2 changes: 1 addition & 1 deletion Resources/config/forms.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<services>
<service id="fos_rest.form.extension.csrf_disable" class="%fos_rest.form.extension.csrf_disable.class%">
<tag name="form.type_extension" alias="form" />
<argument type="service" id="security.context" />
<argument /> <!-- security.token_storage or security.context for Symfony < 2.6 -->
<argument>%fos_rest.disable_csrf_role%</argument>
</service>
</services>
Expand Down
2 changes: 1 addition & 1 deletion Tests/FOSRestBundleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function testBuild()
$container = $this->getMockBuilder('\Symfony\Component\DependencyInjection\ContainerBuilder')
->setMethods(array('addCompilerPass'))
->getMock();
$container->expects($this->exactly(5))
$container->expects($this->exactly(6))
->method('addCompilerPass')
->with($this->isInstanceOf('\Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface'));

Expand Down

0 comments on commit bd233ac

Please sign in to comment.