From 070f925f96ad25614dc58846ea9cc678bfc3e3b3 Mon Sep 17 00:00:00 2001 From: peshi Date: Wed, 10 Jun 2015 22:01:06 +0200 Subject: [PATCH] Updated DisableCSRFExtension for 2.7+ --- .../Compiler/CsrfExtensionPass.php | 34 ++++++++++++++ FOSRestBundle.php | 2 + Form/Extension/DisableCSRFExtension.php | 46 +++++++++++++++---- Resources/config/forms.xml | 2 +- Tests/FOSRestBundleTest.php | 2 +- 5 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 DependencyInjection/Compiler/CsrfExtensionPass.php diff --git a/DependencyInjection/Compiler/CsrfExtensionPass.php b/DependencyInjection/Compiler/CsrfExtensionPass.php new file mode 100644 index 000000000..58ef34824 --- /dev/null +++ b/DependencyInjection/Compiler/CsrfExtensionPass.php @@ -0,0 +1,34 @@ + + * + * 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); + } + } +} diff --git a/FOSRestBundle.php b/FOSRestBundle.php index 50cf2d388..dd09e94a4 100644 --- a/FOSRestBundle.php +++ b/FOSRestBundle.php @@ -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 @@ -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()); } } diff --git a/Form/Extension/DisableCSRFExtension.php b/Form/Extension/DisableCSRFExtension.php index b6548b507..ce2b7eed3 100644 --- a/Form/Extension/DisableCSRFExtension.php +++ b/Form/Extension/DisableCSRFExtension.php @@ -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 @@ -22,23 +25,42 @@ */ 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( @@ -46,6 +68,12 @@ public function setDefaultOptions(OptionsResolverInterface $resolver) )); } + // BC for < 2.7 + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $this->configureOptions($resolver); + } + public function getExtendedType() { return 'form'; diff --git a/Resources/config/forms.xml b/Resources/config/forms.xml index 0f177d5fc..37fd176ad 100644 --- a/Resources/config/forms.xml +++ b/Resources/config/forms.xml @@ -13,7 +13,7 @@ - + %fos_rest.disable_csrf_role% diff --git a/Tests/FOSRestBundleTest.php b/Tests/FOSRestBundleTest.php index 5be7390a5..f795c4339 100644 --- a/Tests/FOSRestBundleTest.php +++ b/Tests/FOSRestBundleTest.php @@ -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'));