|
14 | 14 | use Symfony\Bridge\Twig\TokenParser\FormThemeTokenParser;
|
15 | 15 | use Symfony\Component\Form\FormView;
|
16 | 16 | use Symfony\Component\Form\Exception\FormException;
|
| 17 | +use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; |
17 | 18 | use Symfony\Component\Form\Util\FormUtil;
|
18 | 19 |
|
19 | 20 | /**
|
|
24 | 25 | */
|
25 | 26 | class FormExtension extends \Twig_Extension
|
26 | 27 | {
|
| 28 | + protected $csrfProvider; |
27 | 29 | protected $resources;
|
28 | 30 | protected $blocks;
|
29 | 31 | protected $environment;
|
30 | 32 | protected $themes;
|
31 | 33 | protected $varStack;
|
32 | 34 | protected $template;
|
33 | 35 |
|
34 |
| - public function __construct(array $resources = array()) |
| 36 | + public function __construct(CsrfProviderInterface $csrfProvider, array $resources = array()) |
35 | 37 | {
|
| 38 | + $this->csrfProvider = $csrfProvider; |
36 | 39 | $this->themes = new \SplObjectStorage();
|
37 | 40 | $this->varStack = array();
|
38 | 41 | $this->blocks = new \SplObjectStorage();
|
@@ -81,6 +84,7 @@ public function getFunctions()
|
81 | 84 | 'form_label' => new \Twig_Function_Method($this, 'renderLabel', array('is_safe' => array('html'))),
|
82 | 85 | 'form_row' => new \Twig_Function_Method($this, 'renderRow', array('is_safe' => array('html'))),
|
83 | 86 | 'form_rest' => new \Twig_Function_Method($this, 'renderRest', array('is_safe' => array('html'))),
|
| 87 | + 'csrf_token' => new \Twig_Function_Method($this, 'getCsrfToken'), |
84 | 88 | '_form_is_choice_group' => new \Twig_Function_Method($this, 'isChoiceGroup', array('is_safe' => array('html'))),
|
85 | 89 | '_form_is_choice_selected' => new \Twig_Function_Method($this, 'isChoiceSelected', array('is_safe' => array('html'))),
|
86 | 90 | );
|
@@ -269,6 +273,34 @@ protected function render(FormView $view, $section, array $variables = array())
|
269 | 273 | ));
|
270 | 274 | }
|
271 | 275 |
|
| 276 | + /** |
| 277 | + * Returns a CSRF token. |
| 278 | + * |
| 279 | + * Use this helper for CSRF protection without the overhead of creating a |
| 280 | + * form. |
| 281 | + * |
| 282 | + * <code> |
| 283 | + * <input type="hidden" name="token" value="{{ csrf_token('rm_user_' ~ user.id) }}"> |
| 284 | + * </code> |
| 285 | + * |
| 286 | + * Check the token in your action using the same intention. |
| 287 | + * |
| 288 | + * <code> |
| 289 | + * $csrfProvider = $this->get('form.csrf_provider'); |
| 290 | + * if (!$csrfProvider->isCsrfTokenValid('rm_user_'.$user->getId(), $token)) { |
| 291 | + * throw new \RuntimeException('CSRF attack detected.'); |
| 292 | + * } |
| 293 | + * </code> |
| 294 | + * |
| 295 | + * @param string $intention The intention of the protected action |
| 296 | + * |
| 297 | + * @return string A CSRF token |
| 298 | + */ |
| 299 | + public function getCsrfToken($intention) |
| 300 | + { |
| 301 | + return $this->csrfProvider->generateCsrfToken($intention); |
| 302 | + } |
| 303 | + |
272 | 304 | /**
|
273 | 305 | * Returns the name of the extension.
|
274 | 306 | *
|
|
0 commit comments