Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit bf1e312

Browse filesBrowse files
[Form][FrameworkBundle] Use auto-configuration to make the default CSRF token id apply only to the app; not to bundles
1 parent c6ae4ad commit bf1e312
Copy full SHA for bf1e312

File tree

5 files changed

+48
-9
lines changed
Filter options

5 files changed

+48
-9
lines changed

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+2-4Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ public function load(array $configs, ContainerBuilder $container): void
615615
$container->registerForAutoconfiguration(DataCollectorInterface::class)
616616
->addTag('data_collector');
617617
$container->registerForAutoconfiguration(FormTypeInterface::class)
618-
->addTag('form.type');
618+
->addTag('form.type', ['csrf_token_id' => '%.form.type_extension.csrf.token_id%']);
619619
$container->registerForAutoconfiguration(FormTypeGuesserInterface::class)
620620
->addTag('form.type_guesser');
621621
$container->registerForAutoconfiguration(FormTypeExtensionInterface::class)
@@ -777,9 +777,7 @@ private function registerFormConfiguration(array $config, ContainerBuilder $cont
777777
$container->setParameter('form.type_extension.csrf.enabled', true);
778778
$container->setParameter('form.type_extension.csrf.field_name', $config['form']['csrf_protection']['field_name']);
779779
$container->setParameter('form.type_extension.csrf.field_attr', $config['form']['csrf_protection']['field_attr']);
780-
781-
$container->getDefinition('form.type_extension.csrf')
782-
->replaceArgument(7, $config['form']['csrf_protection']['token_id']);
780+
$container->setParameter('.form.type_extension.csrf.token_id', $config['form']['csrf_protection']['token_id']);
783781
} else {
784782
$container->setParameter('form.type_extension.csrf.enabled', false);
785783
}

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/form_csrf.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/form_csrf.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
param('validator.translation_domain'),
2525
service('form.server_params'),
2626
param('form.type_extension.csrf.field_attr'),
27-
abstract_arg('framework.form.csrf_protection.token_id'),
27+
param('.form.type_extension.csrf.token_id'),
2828
])
2929
->tag('form.type_extension')
3030
;

‎src/Symfony/Component/Form/DependencyInjection/FormPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/DependencyInjection/FormPass.php
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,18 @@ private function processFormTypes(ContainerBuilder $container): Reference
4747
// Get service locator argument
4848
$servicesMap = [];
4949
$namespaces = ['Symfony\Component\Form\Extension\Core\Type' => true];
50+
$csrfTokenIds = [];
5051

5152
// Builds an array with fully-qualified type class names as keys and service IDs as values
5253
foreach ($container->findTaggedServiceIds('form.type', true) as $serviceId => $tag) {
5354
// Add form type service to the service locator
5455
$serviceDefinition = $container->getDefinition($serviceId);
5556
$servicesMap[$formType = $serviceDefinition->getClass()] = new Reference($serviceId);
5657
$namespaces[substr($formType, 0, strrpos($formType, '\\'))] = true;
58+
59+
if (isset($tag[0]['csrf_token_id'])) {
60+
$csrfTokenIds[$formType] = $tag[0]['csrf_token_id'];
61+
}
5762
}
5863

5964
if ($container->hasDefinition('console.command.form_debug')) {
@@ -62,6 +67,14 @@ private function processFormTypes(ContainerBuilder $container): Reference
6267
$commandDefinition->setArgument(2, array_keys($servicesMap));
6368
}
6469

70+
if ($csrfTokenIds && $container->hasDefinition('form.type_extension.csrf')) {
71+
$csrfExtension = $container->getDefinition('form.type_extension.csrf');
72+
73+
if (8 <= \count($csrfExtension->getArguments())) {
74+
$csrfExtension->replaceArgument(7, $csrfTokenIds);
75+
}
76+
}
77+
6578
return ServiceLocatorTagPass::register($container, $servicesMap);
6679
}
6780

‎src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/Csrf/Type/FormTypeCsrfExtension.php
+12-4Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function __construct(
3737
private ?string $translationDomain = null,
3838
private ?ServerParams $serverParams = null,
3939
private array $fieldAttr = [],
40-
private ?string $defaultTokenId = null,
40+
private string|array|null $defaultTokenId = null,
4141
) {
4242
}
4343

@@ -50,11 +50,17 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
5050
return;
5151
}
5252

53+
$csrfTokenId = $options['csrf_token_id']
54+
?: $this->defaultTokenId[$builder->getType()->getInnerType()::class]
55+
?? $builder->getName()
56+
?: $builder->getType()->getInnerType()::class;
57+
$builder->setAttribute('csrf_token_id', $csrfTokenId);
58+
5359
$builder
5460
->addEventSubscriber(new CsrfValidationListener(
5561
$options['csrf_field_name'],
5662
$options['csrf_token_manager'],
57-
$options['csrf_token_id'] ?: ($builder->getName() ?: $builder->getType()->getInnerType()::class),
63+
$csrfTokenId,
5864
$options['csrf_message'],
5965
$this->translator,
6066
$this->translationDomain,
@@ -70,7 +76,7 @@ public function finishView(FormView $view, FormInterface $form, array $options):
7076
{
7177
if ($options['csrf_protection'] && !$view->parent && $options['compound']) {
7278
$factory = $form->getConfig()->getFormFactory();
73-
$tokenId = $options['csrf_token_id'] ?: ($form->getName() ?: $form->getConfig()->getType()->getInnerType()::class);
79+
$tokenId = $form->getConfig()->getAttribute('csrf_token_id');
7480
$data = (string) $options['csrf_token_manager']->getToken($tokenId);
7581

7682
$csrfForm = $factory->createNamed($options['csrf_field_name'], HiddenType::class, $data, [
@@ -85,9 +91,11 @@ public function finishView(FormView $view, FormInterface $form, array $options):
8591

8692
public function configureOptions(OptionsResolver $resolver): void
8793
{
88-
if ($defaultTokenId = $this->defaultTokenId) {
94+
if (\is_string($defaultTokenId = $this->defaultTokenId) && $defaultTokenId) {
8995
$defaultTokenManager = $this->defaultTokenManager;
9096
$defaultTokenId = static fn (Options $options) => $options['csrf_token_manager'] === $defaultTokenManager ? $defaultTokenId : null;
97+
} else {
98+
$defaultTokenId = null;
9199
}
92100

93101
$resolver->setDefaults([

‎src/Symfony/Component/Form/Tests/DependencyInjection/FormPassTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/DependencyInjection/FormPassTest.php
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Symfony\Component\Form\AbstractTypeExtension;
2222
use Symfony\Component\Form\Command\DebugCommand;
2323
use Symfony\Component\Form\DependencyInjection\FormPass;
24+
use Symfony\Component\Form\Extension\Csrf\Type\FormTypeCsrfExtension;
2425
use Symfony\Component\Form\FormRegistry;
2526

2627
/**
@@ -95,6 +96,25 @@ public function testAddTaggedTypesToDebugCommand()
9596
);
9697
}
9798

99+
public function testAddTaggedTypesToCsrfTypeExtension()
100+
{
101+
$container = $this->createContainerBuilder();
102+
103+
$container->register('form.registry', FormRegistry::class);
104+
$container->register('form.type_extension.csrf', FormTypeCsrfExtension::class)
105+
->setArguments([null, true, '_token', null, 'validator.translation_domain', null, [], null])
106+
->setPublic(true);
107+
108+
$container->setDefinition('form.extension', $this->createExtensionDefinition());
109+
$container->register('my.type1', __CLASS__.'_Type1')->addTag('form.type', ['csrf_token_id' => 'the_token_id']);
110+
$container->register('my.type2', __CLASS__.'_Type2')->addTag('form.type');
111+
112+
$container->compile();
113+
114+
$csrfDefinition = $container->getDefinition('form.type_extension.csrf');
115+
$this->assertSame([__CLASS__.'_Type1' => 'the_token_id'], $csrfDefinition->getArgument(7));
116+
}
117+
98118
/**
99119
* @dataProvider addTaggedTypeExtensionsDataProvider
100120
*/

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.