diff options
Diffstat (limited to 'vendor/symfony/form/Symfony/Component/Form/Extension/Csrf')
6 files changed, 492 insertions, 0 deletions
diff --git a/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfExtension.php b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfExtension.php new file mode 100644 index 00000000..f9d9e40a --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfExtension.php | |||
@@ -0,0 +1,64 @@ | |||
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\Component\Form\Extension\Csrf; | ||
13 | |||
14 | use Symfony\Component\Form\Extension\Csrf\Type; | ||
15 | use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; | ||
16 | use Symfony\Component\Form\AbstractExtension; | ||
17 | use Symfony\Component\Translation\TranslatorInterface; | ||
18 | |||
19 | /** | ||
20 | * This extension protects forms by using a CSRF token. | ||
21 | * | ||
22 | * @author Bernhard Schussek <bschussek@gmail.com> | ||
23 | */ | ||
24 | class CsrfExtension extends AbstractExtension | ||
25 | { | ||
26 | /** | ||
27 | * @var CsrfProviderInterface | ||
28 | */ | ||
29 | private $csrfProvider; | ||
30 | |||
31 | /** | ||
32 | * @var TranslatorInterface | ||
33 | */ | ||
34 | private $translator; | ||
35 | |||
36 | /** | ||
37 | * @var null|string | ||
38 | */ | ||
39 | private $translationDomain; | ||
40 | |||
41 | /** | ||
42 | * Constructor. | ||
43 | * | ||
44 | * @param CsrfProviderInterface $csrfProvider The CSRF provider | ||
45 | * @param TranslatorInterface $translator The translator for translating error messages. | ||
46 | * @param null|string $translationDomain The translation domain for translating. | ||
47 | */ | ||
48 | public function __construct(CsrfProviderInterface $csrfProvider, TranslatorInterface $translator = null, $translationDomain = null) | ||
49 | { | ||
50 | $this->csrfProvider = $csrfProvider; | ||
51 | $this->translator = $translator; | ||
52 | $this->translationDomain = $translationDomain; | ||
53 | } | ||
54 | |||
55 | /** | ||
56 | * {@inheritDoc} | ||
57 | */ | ||
58 | protected function loadTypeExtensions() | ||
59 | { | ||
60 | return array( | ||
61 | new Type\FormTypeCsrfExtension($this->csrfProvider, true, '_token', $this->translator, $this->translationDomain), | ||
62 | ); | ||
63 | } | ||
64 | } | ||
diff --git a/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/CsrfProviderInterface.php b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/CsrfProviderInterface.php new file mode 100644 index 00000000..7143b130 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/CsrfProviderInterface.php | |||
@@ -0,0 +1,49 @@ | |||
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\Component\Form\Extension\Csrf\CsrfProvider; | ||
13 | |||
14 | /** | ||
15 | * Marks classes able to provide CSRF protection | ||
16 | * | ||
17 | * You can generate a CSRF token by using the method generateCsrfToken(). To | ||
18 | * this method you should pass a value that is unique to the page that should | ||
19 | * be secured against CSRF attacks. This value doesn't necessarily have to be | ||
20 | * secret. Implementations of this interface are responsible for adding more | ||
21 | * secret information. | ||
22 | * | ||
23 | * If you want to secure a form submission against CSRF attacks, you could | ||
24 | * supply an "intention" string. This way you make sure that the form can only | ||
25 | * be submitted to pages that are designed to handle the form, that is, that use | ||
26 | * the same intention string to validate the CSRF token with isCsrfTokenValid(). | ||
27 | * | ||
28 | * @author Bernhard Schussek <bschussek@gmail.com> | ||
29 | */ | ||
30 | interface CsrfProviderInterface | ||
31 | { | ||
32 | /** | ||
33 | * Generates a CSRF token for a page of your application. | ||
34 | * | ||
35 | * @param string $intention Some value that identifies the action intention | ||
36 | * (i.e. "authenticate"). Doesn't have to be a secret value. | ||
37 | */ | ||
38 | public function generateCsrfToken($intention); | ||
39 | |||
40 | /** | ||
41 | * Validates a CSRF token. | ||
42 | * | ||
43 | * @param string $intention The intention used when generating the CSRF token | ||
44 | * @param string $token The token supplied by the browser | ||
45 | * | ||
46 | * @return Boolean Whether the token supplied by the browser is correct | ||
47 | */ | ||
48 | public function isCsrfTokenValid($intention, $token); | ||
49 | } | ||
diff --git a/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/DefaultCsrfProvider.php b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/DefaultCsrfProvider.php new file mode 100644 index 00000000..5354886c --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/DefaultCsrfProvider.php | |||
@@ -0,0 +1,78 @@ | |||
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\Component\Form\Extension\Csrf\CsrfProvider; | ||
13 | |||
14 | /** | ||
15 | * Default implementation of CsrfProviderInterface. | ||
16 | * | ||
17 | * This provider uses the session ID returned by session_id() as well as a | ||
18 | * user-defined secret value to secure the CSRF token. | ||
19 | * | ||
20 | * @author Bernhard Schussek <bschussek@gmail.com> | ||
21 | */ | ||
22 | class DefaultCsrfProvider implements CsrfProviderInterface | ||
23 | { | ||
24 | /** | ||
25 | * A secret value used for generating the CSRF token | ||
26 | * @var string | ||
27 | */ | ||
28 | protected $secret; | ||
29 | |||
30 | /** | ||
31 | * Initializes the provider with a secret value | ||
32 | * | ||
33 | * A recommended value for the secret is a generated value with at least | ||
34 | * 32 characters and mixed letters, digits and special characters. | ||
35 | * | ||
36 | * @param string $secret A secret value included in the CSRF token | ||
37 | */ | ||
38 | public function __construct($secret) | ||
39 | { | ||
40 | $this->secret = $secret; | ||
41 | } | ||
42 | |||
43 | /** | ||
44 | * {@inheritDoc} | ||
45 | */ | ||
46 | public function generateCsrfToken($intention) | ||
47 | { | ||
48 | return sha1($this->secret.$intention.$this->getSessionId()); | ||
49 | } | ||
50 | |||
51 | /** | ||
52 | * {@inheritDoc} | ||
53 | */ | ||
54 | public function isCsrfTokenValid($intention, $token) | ||
55 | { | ||
56 | return $token === $this->generateCsrfToken($intention); | ||
57 | } | ||
58 | |||
59 | /** | ||
60 | * Returns the ID of the user session. | ||
61 | * | ||
62 | * Automatically starts the session if necessary. | ||
63 | * | ||
64 | * @return string The session ID | ||
65 | */ | ||
66 | protected function getSessionId() | ||
67 | { | ||
68 | if (version_compare(PHP_VERSION, '5.4', '>=')) { | ||
69 | if (PHP_SESSION_NONE === session_status()) { | ||
70 | session_start(); | ||
71 | } | ||
72 | } elseif (!session_id()) { | ||
73 | session_start(); | ||
74 | } | ||
75 | |||
76 | return session_id(); | ||
77 | } | ||
78 | } | ||
diff --git a/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/SessionCsrfProvider.php b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/SessionCsrfProvider.php new file mode 100644 index 00000000..ea1fa585 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/CsrfProvider/SessionCsrfProvider.php | |||
@@ -0,0 +1,57 @@ | |||
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\Component\Form\Extension\Csrf\CsrfProvider; | ||
13 | |||
14 | use Symfony\Component\HttpFoundation\Session\Session; | ||
15 | |||
16 | /** | ||
17 | * This provider uses a Symfony2 Session object to retrieve the user's | ||
18 | * session ID. | ||
19 | * | ||
20 | * @see DefaultCsrfProvider | ||
21 | * | ||
22 | * @author Bernhard Schussek <bschussek@gmail.com> | ||
23 | */ | ||
24 | class SessionCsrfProvider extends DefaultCsrfProvider | ||
25 | { | ||
26 | /** | ||
27 | * The user session from which the session ID is returned | ||
28 | * @var Session | ||
29 | */ | ||
30 | protected $session; | ||
31 | |||
32 | /** | ||
33 | * Initializes the provider with a Session object and a secret value. | ||
34 | * | ||
35 | * A recommended value for the secret is a generated value with at least | ||
36 | * 32 characters and mixed letters, digits and special characters. | ||
37 | * | ||
38 | * @param Session $session The user session | ||
39 | * @param string $secret A secret value included in the CSRF token | ||
40 | */ | ||
41 | public function __construct(Session $session, $secret) | ||
42 | { | ||
43 | parent::__construct($secret); | ||
44 | |||
45 | $this->session = $session; | ||
46 | } | ||
47 | |||
48 | /** | ||
49 | * {@inheritdoc} | ||
50 | */ | ||
51 | protected function getSessionId() | ||
52 | { | ||
53 | $this->session->start(); | ||
54 | |||
55 | return $this->session->getId(); | ||
56 | } | ||
57 | } | ||
diff --git a/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php new file mode 100644 index 00000000..547e9d75 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php | |||
@@ -0,0 +1,115 @@ | |||
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\Component\Form\Extension\Csrf\EventListener; | ||
13 | |||
14 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; | ||
15 | use Symfony\Component\Form\FormEvents; | ||
16 | use Symfony\Component\Form\FormError; | ||
17 | use Symfony\Component\Form\FormEvent; | ||
18 | use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; | ||
19 | use Symfony\Component\Translation\TranslatorInterface; | ||
20 | |||
21 | /** | ||
22 | * @author Bernhard Schussek <bschussek@gmail.com> | ||
23 | */ | ||
24 | class CsrfValidationListener implements EventSubscriberInterface | ||
25 | { | ||
26 | /** | ||
27 | * The name of the CSRF field | ||
28 | * @var string | ||
29 | */ | ||
30 | private $fieldName; | ||
31 | |||
32 | /** | ||
33 | * The provider for generating and validating CSRF tokens | ||
34 | * @var CsrfProviderInterface | ||
35 | */ | ||
36 | private $csrfProvider; | ||
37 | |||
38 | /** | ||
39 | * A text mentioning the intention of the CSRF token | ||
40 | * | ||
41 | * Validation of the token will only succeed if it was generated in the | ||
42 | * same session and with the same intention. | ||
43 | * | ||
44 | * @var string | ||
45 | */ | ||
46 | private $intention; | ||
47 | |||
48 | /** | ||
49 | * The message displayed in case of an error. | ||
50 | * @var string | ||
51 | */ | ||
52 | private $errorMessage; | ||
53 | |||
54 | /** | ||
55 | * @var TranslatorInterface | ||
56 | */ | ||
57 | private $translator; | ||
58 | |||
59 | /** | ||
60 | * @var null|string | ||
61 | */ | ||
62 | private $translationDomain; | ||
63 | |||
64 | public static function getSubscribedEvents() | ||
65 | { | ||
66 | return array( | ||
67 | FormEvents::PRE_SUBMIT => 'preSubmit', | ||
68 | ); | ||
69 | } | ||
70 | |||
71 | public function __construct($fieldName, CsrfProviderInterface $csrfProvider, $intention, $errorMessage, TranslatorInterface $translator = null, $translationDomain = null) | ||
72 | { | ||
73 | $this->fieldName = $fieldName; | ||
74 | $this->csrfProvider = $csrfProvider; | ||
75 | $this->intention = $intention; | ||
76 | $this->errorMessage = $errorMessage; | ||
77 | $this->translator = $translator; | ||
78 | $this->translationDomain = $translationDomain; | ||
79 | } | ||
80 | |||
81 | public function preSubmit(FormEvent $event) | ||
82 | { | ||
83 | $form = $event->getForm(); | ||
84 | $data = $event->getData(); | ||
85 | |||
86 | if ($form->isRoot() && $form->getConfig()->getOption('compound')) { | ||
87 | if (!isset($data[$this->fieldName]) || !$this->csrfProvider->isCsrfTokenValid($this->intention, $data[$this->fieldName])) { | ||
88 | $errorMessage = $this->errorMessage; | ||
89 | |||
90 | if (null !== $this->translator) { | ||
91 | $errorMessage = $this->translator->trans($errorMessage, array(), $this->translationDomain); | ||
92 | } | ||
93 | |||
94 | $form->addError(new FormError($errorMessage)); | ||
95 | } | ||
96 | |||
97 | if (is_array($data)) { | ||
98 | unset($data[$this->fieldName]); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | $event->setData($data); | ||
103 | } | ||
104 | |||
105 | /** | ||
106 | * Alias of {@link preSubmit()}. | ||
107 | * | ||
108 | * @deprecated Deprecated since version 2.3, to be removed in 3.0. Use | ||
109 | * {@link preSubmit()} instead. | ||
110 | */ | ||
111 | public function preBind(FormEvent $event) | ||
112 | { | ||
113 | $this->preSubmit($event); | ||
114 | } | ||
115 | } | ||
diff --git a/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php new file mode 100644 index 00000000..336cf047 --- /dev/null +++ b/vendor/symfony/form/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php | |||
@@ -0,0 +1,129 @@ | |||
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\Component\Form\Extension\Csrf\Type; | ||
13 | |||
14 | use Symfony\Component\Form\AbstractTypeExtension; | ||
15 | use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface; | ||
16 | use Symfony\Component\Form\Extension\Csrf\EventListener\CsrfValidationListener; | ||
17 | use Symfony\Component\Form\FormBuilderInterface; | ||
18 | use Symfony\Component\Form\FormView; | ||
19 | use Symfony\Component\Form\FormInterface; | ||
20 | use Symfony\Component\OptionsResolver\OptionsResolverInterface; | ||
21 | use Symfony\Component\Translation\TranslatorInterface; | ||
22 | |||
23 | /** | ||
24 | * @author Bernhard Schussek <bschussek@gmail.com> | ||
25 | */ | ||
26 | class FormTypeCsrfExtension extends AbstractTypeExtension | ||
27 | { | ||
28 | /** | ||
29 | * @var CsrfProviderInterface | ||
30 | */ | ||
31 | private $defaultCsrfProvider; | ||
32 | |||
33 | /** | ||
34 | * @var Boolean | ||
35 | */ | ||
36 | private $defaultEnabled; | ||
37 | |||
38 | /** | ||
39 | * @var string | ||
40 | */ | ||
41 | private $defaultFieldName; | ||
42 | |||
43 | /** | ||
44 | * @var TranslatorInterface | ||
45 | */ | ||
46 | private $translator; | ||
47 | |||
48 | /** | ||
49 | * @var null|string | ||
50 | */ | ||
51 | private $translationDomain; | ||
52 | |||
53 | public function __construct(CsrfProviderInterface $defaultCsrfProvider, $defaultEnabled = true, $defaultFieldName = '_token', TranslatorInterface $translator = null, $translationDomain = null) | ||
54 | { | ||
55 | $this->defaultCsrfProvider = $defaultCsrfProvider; | ||
56 | $this->defaultEnabled = $defaultEnabled; | ||
57 | $this->defaultFieldName = $defaultFieldName; | ||
58 | $this->translator = $translator; | ||
59 | $this->translationDomain = $translationDomain; | ||
60 | } | ||
61 | |||
62 | /** | ||
63 | * Adds a CSRF field to the form when the CSRF protection is enabled. | ||
64 | * | ||
65 | * @param FormBuilderInterface $builder The form builder | ||
66 | * @param array $options The options | ||
67 | */ | ||
68 | public function buildForm(FormBuilderInterface $builder, array $options) | ||
69 | { | ||
70 | if (!$options['csrf_protection']) { | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | $builder | ||
75 | ->setAttribute('csrf_factory', $builder->getFormFactory()) | ||
76 | ->addEventSubscriber(new CsrfValidationListener( | ||
77 | $options['csrf_field_name'], | ||
78 | $options['csrf_provider'], | ||
79 | $options['intention'], | ||
80 | $options['csrf_message'], | ||
81 | $this->translator, | ||
82 | $this->translationDomain | ||
83 | )) | ||
84 | ; | ||
85 | } | ||
86 | |||
87 | /** | ||
88 | * Adds a CSRF field to the root form view. | ||
89 | * | ||
90 | * @param FormView $view The form view | ||
91 | * @param FormInterface $form The form | ||
92 | * @param array $options The options | ||
93 | */ | ||
94 | public function finishView(FormView $view, FormInterface $form, array $options) | ||
95 | { | ||
96 | if ($options['csrf_protection'] && !$view->parent && $options['compound']) { | ||
97 | $factory = $form->getConfig()->getAttribute('csrf_factory'); | ||
98 | $data = $options['csrf_provider']->generateCsrfToken($options['intention']); | ||
99 | |||
100 | $csrfForm = $factory->createNamed($options['csrf_field_name'], 'hidden', $data, array( | ||
101 | 'mapped' => false, | ||
102 | )); | ||
103 | |||
104 | $view->children[$options['csrf_field_name']] = $csrfForm->createView($view); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | /** | ||
109 | * {@inheritDoc} | ||
110 | */ | ||
111 | public function setDefaultOptions(OptionsResolverInterface $resolver) | ||
112 | { | ||
113 | $resolver->setDefaults(array( | ||
114 | 'csrf_protection' => $this->defaultEnabled, | ||
115 | 'csrf_field_name' => $this->defaultFieldName, | ||
116 | 'csrf_provider' => $this->defaultCsrfProvider, | ||
117 | 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', | ||
118 | 'intention' => 'unknown', | ||
119 | )); | ||
120 | } | ||
121 | |||
122 | /** | ||
123 | * {@inheritDoc} | ||
124 | */ | ||
125 | public function getExtendedType() | ||
126 | { | ||
127 | return 'form'; | ||
128 | } | ||
129 | } | ||