Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
349 changes: 173 additions & 176 deletions src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2291,10 +2291,6 @@ private function registerLockConfiguration(array $config, ContainerBuilder $cont
// Generate stores
$storeDefinitions = [];
foreach ($resourceStores as $resourceStore) {
if (null === $resourceStore) {
$resourceStore = 'null';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this concern is now handled in the configuration L1532

}

$storeDsn = $container->resolveEnvPlaceholders($resourceStore, null, $usedEnvs);
if (!$usedEnvs && !str_contains($resourceStore, ':') && !\in_array($resourceStore, ['flock', 'semaphore', 'in-memory', 'null'], true)) {
$resourceStore = new Reference($resourceStore);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,36 +72,6 @@ public function testAssetPackageCannotHavePathAndUrl()
});
}

public function testWorkflowValidationPlacesIsArray()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 2 test cases used to cover a custom implementation of validation logic that is now replaced by built-in validation done by the config component; which is already tested separately.

{
$this->expectException(InvalidConfigurationException::class);
$this->expectExceptionMessage('The "places" option must be an array or a "FQCN::glob" pattern in workflow configuration.');
$this->createContainerFromClosure(function ($container) {
$container->loadFromExtension('framework', [
'workflows' => [
'article' => [
'places' => null,
],
],
]);
});
}

public function testWorkflowValidationTransitonsIsArray()
{
$this->expectException(InvalidConfigurationException::class);
$this->expectExceptionMessage('The "transitions" option must be an array in workflow configuration.');
$this->createContainerFromClosure(function ($container) {
$container->loadFromExtension('framework', [
'workflows' => [
'article' => [
'transitions' => null,
],
],
]);
});
}

public function testWorkflowValidationStateMachine()
{
$this->expectException(InvalidDefinitionException::class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ public function getConfigTreeBuilder(): TreeBuilder
$rootNode
->docUrl('https://symfony.com/doc/{version:major}.{version:minor}/reference/configuration/security.html', 'symfony/security-bundle')
->beforeNormalization()
->always()
->then(function ($v) {
->ifArray()
->then(static function ($v) {
if (isset($v['hide_user_not_found']) && isset($v['expose_security_errors'])) {
throw new InvalidConfigurationException('You cannot use both "hide_user_not_found" and "expose_security_errors" at the same time.');
}
Expand All @@ -80,7 +80,7 @@ public function getConfigTreeBuilder(): TreeBuilder
->setDeprecated('symfony/security-bundle', '7.3', 'The "%node%" option is deprecated and will be removed in 8.0. Use the "expose_security_errors" option instead.')
->end()
->enumNode('expose_security_errors')
->beforeNormalization()->ifString()->then(fn ($v) => ExposeSecurityLevel::tryFrom($v))->end()
->beforeNormalization()->ifString()->then(static fn ($v) => ExposeSecurityLevel::tryFrom($v))->end()
->values(ExposeSecurityLevel::cases())
->defaultValue(ExposeSecurityLevel::None)
->end()
Expand Down Expand Up @@ -129,11 +129,7 @@ private function addRoleHierarchySection(ArrayNodeDefinition $rootNode): void
->useAttributeAsKey('id')
->prototype('array')
->performNoDeepMerging()
->beforeNormalization()->ifString()->then(fn ($v) => ['value' => $v])->end()
->beforeNormalization()
->ifTrue(fn ($v) => \is_array($v) && isset($v['value']))
->then(fn ($v) => preg_split('/\s*,\s*/', $v['value']))
->end()
->beforeNormalization()->ifString()->then(static fn ($v) => preg_split('/\s*,\s*/', $v))->end()
->prototype('scalar')->end()
->end()
->end()
Expand All @@ -159,7 +155,7 @@ private function addAccessControlSection(ArrayNodeDefinition $rootNode): void
->scalarNode('host')->defaultNull()->end()
->integerNode('port')->defaultNull()->end()
->arrayNode('ips', 'ip')
->beforeNormalization()->ifString()->then(fn ($v) => [$v])->end()
->acceptAndWrap(['string'])
->prototype('scalar')->end()
->end()
->arrayNode('attributes', 'attribute')
Expand All @@ -168,14 +164,14 @@ private function addAccessControlSection(ArrayNodeDefinition $rootNode): void
->end()
->scalarNode('route')->defaultNull()->end()
->arrayNode('methods', 'method')
->beforeNormalization()->ifString()->then(fn ($v) => preg_split('/\s*,\s*/', $v))->end()
->beforeNormalization()->ifString()->then(static fn ($v) => preg_split('/\s*,\s*/', $v))->end()
->prototype('scalar')->end()
->end()
->scalarNode('allow_if')->defaultNull()->end()
->end()
->children()
->arrayNode('roles', 'role')
->beforeNormalization()->ifString()->then(fn ($v) => preg_split('/\s*,\s*/', $v))->end()
->beforeNormalization()->ifString()->then(static fn ($v) => preg_split('/\s*,\s*/', $v))->end()
->prototype('scalar')->end()
->end()
->end()
Expand Down Expand Up @@ -205,12 +201,12 @@ private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $facto
->scalarNode('pattern')
->beforeNormalization()
->ifArray()
->then(fn ($v) => \sprintf('(?:%s)', implode('|', $v)))
->then(static fn ($v) => \sprintf('(?:%s)', implode('|', $v)))
->end()
->end()
->scalarNode('host')->end()
->arrayNode('methods')
->beforeNormalization()->ifString()->then(fn ($v) => preg_split('/\s*,\s*/', $v))->end()
->beforeNormalization()->ifString()->then(static fn ($v) => preg_split('/\s*,\s*/', $v))->end()
->prototype('scalar')->end()
->end()
->booleanNode('security')->defaultTrue()->end()
Expand All @@ -233,11 +229,11 @@ private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $facto
->treatTrueLike([])
->canBeUnset()
->beforeNormalization()
->ifTrue(fn ($v): bool => \is_array($v) && (isset($v['csrf_token_manager']) xor isset($v['enable_csrf'])))
->then(function (array $v): array {
->ifArray()
->then(static function ($v) {
if (isset($v['csrf_token_manager'])) {
$v['enable_csrf'] = true;
} elseif ($v['enable_csrf']) {
$v['enable_csrf'] ??= true;
} elseif ($v['enable_csrf'] ?? false) {
$v['csrf_token_manager'] = 'security.csrf.token_manager';
}

Expand All @@ -254,7 +250,7 @@ private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $facto
->booleanNode('invalidate_session')->defaultTrue()->end()
->arrayNode('clear_site_data')
->performNoDeepMerging()
->beforeNormalization()->ifString()->then(fn ($v) => $v ? array_map('trim', explode(',', $v)) : [])->end()
->beforeNormalization()->ifString()->then(static fn ($v) => $v ? array_map('trim', explode(',', $v)) : [])->end()
->enumPrototype()
->values([
'*', 'cache', 'cookies', 'storage', 'executionContexts',
Expand All @@ -265,9 +261,10 @@ private function addFirewallsSection(ArrayNodeDefinition $rootNode, array $facto
->children()
->arrayNode('delete_cookies', 'delete_cookie')
->normalizeKeys(false)
->acceptAndWrap(['string'])
->beforeNormalization()
->ifTrue(fn ($v) => \is_array($v) && \is_int(key($v)))
->then(fn ($v) => array_map(fn ($v) => ['name' => $v], $v))
->ifArray()
->then(static fn ($v) => array_map(static fn ($v) => \is_string($v) ? ['name' => $v] : $v, $v))
->end()
->useAttributeAsKey('name')
->prototype('array')
Expand Down Expand Up @@ -379,10 +376,7 @@ private function addProvidersSection(ArrayNodeDefinition $rootNode): void
->arrayNode('chain')
->children()
->arrayNode('providers', 'provider')
->beforeNormalization()
->ifString()
->then(fn ($v) => preg_split('/\s*,\s*/', $v))
->end()
->beforeNormalization()->ifString()->then(static fn ($v) => preg_split('/\s*,\s*/', $v))->end()
->prototype('scalar')->end()
->end()
->end()
Expand Down Expand Up @@ -427,7 +421,7 @@ private function addPasswordHashersSection(ArrayNodeDefinition $rootNode): void
->prototype('array')
->canBeUnset()
->performNoDeepMerging()
->beforeNormalization()->ifString()->then(fn ($v) => ['algorithm' => $v])->end()
->acceptAndWrap(['string'], 'algorithm')
->children()
->scalarNode('algorithm')
->cannotBeEmpty()
Expand All @@ -437,8 +431,8 @@ private function addPasswordHashersSection(ArrayNodeDefinition $rootNode): void
->end()
->end()
->arrayNode('migrate_from')
->acceptAndWrap(['string'])
->prototype('scalar')->end()
->beforeNormalization()->castToArray()->end()
->end()
->scalarNode('hash_algorithm')->info('Name of hashing algorithm for PBKDF2 (i.e. sha256, sha512, etc..) See hash_algos() for a list of supported algorithms.')->defaultValue('sha512')->end()
->scalarNode('key_length')->defaultValue(40)->end()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,24 +99,28 @@ public function addConfiguration(NodeBuilder $node): void
->thenInvalid('You must set either "discovery" or "key" or "keyset".')
->end()
->beforeNormalization()
->ifTrue(static fn ($v) => isset($v['algorithm']) && \is_string($v['algorithm']))
->ifArray()
->then(static function ($v) {
if (isset($v['algorithms'])) {
if (isset($v['algorithms']) && isset($v['algorithm'])) {
throw new InvalidConfigurationException('You cannot use both "algorithm" and "algorithms" at the same time.');
}
$v['algorithms'] = [$v['algorithm']];
unset($v['algorithm']);
if (\is_string($v['algorithm'] ?? null)) {
$v['algorithms'] = [$v['algorithm']];
unset($v['algorithm']);
}

return $v;
})
->end()
->beforeNormalization()
->ifTrue(static fn ($v) => isset($v['key']) && \is_string($v['key']))
->ifArray()
->then(static function ($v) {
if (isset($v['keyset'])) {
if (isset($v['keyset']) && isset($v['key'])) {
throw new InvalidConfigurationException('You cannot use both "key" and "keyset" at the same time.');
}
$v['keyset'] = \sprintf('{"keys":[%s]}', $v['key']);
if (\is_string($v['key'] ?? null)) {
$v['keyset'] = \sprintf('{"keys":[%s]}', $v['key']);
}

return $v;
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public function addConfiguration(NodeBuilder $node): void
->arrayNode($this->getKey())
->beforeNormalization()
->ifString()
->then(fn ($v) => ['claim' => 'sub', 'base_uri' => $v])
->then(static fn ($v) => ['claim' => 'sub', 'base_uri' => $v])
->end()
->children()
->scalarNode('base_uri')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,39 +47,28 @@ public function addConfiguration(NodeDefinition $node): void
$builder
->scalarNode('realm')->defaultNull()->end()
->arrayNode('token_extractors', 'token_extractor')
->beforeNormalization()
->ifString()
->then(fn ($v) => [$v])
->end()
->acceptAndWrap(['string'])
->cannotBeEmpty()
->defaultValue([
'security.access_token_extractor.header',
])
->defaultValue(['security.access_token_extractor.header'])
->scalarPrototype()->end()
->end()
;

$tokenHandlerNodeBuilder = $builder
->arrayNode('token_handler')
->example([
'id' => 'App\Security\CustomTokenHandler',
])

->beforeNormalization()
->ifString()
->then(fn ($v) => ['id' => $v])
->end()
->example(['id' => 'App\Security\CustomTokenHandler'])
->acceptAndWrap(['string'], 'id')

->beforeNormalization()
->ifTrue(fn ($v) => \is_array($v) && 1 < \count($v))
->then(fn () => throw new InvalidConfigurationException('You cannot configure multiple token handlers.'))
->validate()
->ifTrue(static fn ($v) => \is_array($v) && 1 < \count($v))
->then(static fn () => throw new InvalidConfigurationException('You cannot configure multiple token handlers.'))
->end()

// "isRequired" must be set otherwise the following custom validation is not called
->isRequired()
->beforeNormalization()
->ifTrue(fn ($v) => \is_array($v) && !$v)
->then(fn () => throw new InvalidConfigurationException('You must set a token handler.'))
->validate()
->ifTrue(static fn ($v) => \is_array($v) && !$v)
->then(static fn () => throw new InvalidConfigurationException('You must set a token handler.'))
->end()

->children()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,7 @@ public function addConfiguration(NodeDefinition $node): void
->end()
->scalarNode('service')->end()
->arrayNode('user_providers', 'user_provider')
->beforeNormalization()
->ifString()->then(fn ($v) => [$v])
->end()
->acceptAndWrap(['string'])
->prototype('scalar')->end()
->end()
->booleanNode('catch_exceptions')->defaultTrue()->end()
Expand All @@ -147,11 +145,9 @@ public function addConfiguration(NodeDefinition $node): void
->defaultValue(['password'])
->end()
->arrayNode('token_provider')
->beforeNormalization()
->ifString()->then(fn ($v) => ['service' => $v])
->end()
->acceptAndWrap(['string'], 'service')
->children()
->scalarNode('service')->info('The service ID of a custom rememberme token provider.')->end()
->scalarNode('service')->info('The service ID of a custom remember-me token provider.')->end()
->arrayNode('doctrine')
->canBeEnabled()
->children()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider;

use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand Down Expand Up @@ -42,7 +43,10 @@
return 'memory';
}

/**
* @param ArrayNodeDefinition $node
*/
public function addConfiguration(NodeDefinition $node): void

Check failure on line 49 in src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php

View workflow job for this annotation

GitHub Actions / Psalm

MoreSpecificImplementedParamType

src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php:49:53: MoreSpecificImplementedParamType: Argument 1 of Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\InMemoryFactory::addConfiguration has the more specific type 'Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition', expecting 'Symfony\Component\Config\Definition\Builder\NodeDefinition' as defined by Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface::addConfiguration (see https://psalm.dev/140)

Check failure on line 49 in src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php

View workflow job for this annotation

GitHub Actions / Psalm

MoreSpecificImplementedParamType

src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/InMemoryFactory.php:49:53: MoreSpecificImplementedParamType: Argument 1 of Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\InMemoryFactory::addConfiguration has the more specific type 'Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition', expecting 'Symfony\Component\Config\Definition\Builder\NodeDefinition' as defined by Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface::addConfiguration (see https://psalm.dev/140)
{
$node
->children()
Expand All @@ -53,7 +57,7 @@
->children()
->scalarNode('password')->defaultNull()->end()
->arrayNode('roles')
->beforeNormalization()->ifString()->then(fn ($v) => preg_split('/\s*,\s*/', $v))->end()
->beforeNormalization()->ifString()->then(static fn ($v) => preg_split('/\s*,\s*/', $v))->end()
->prototype('scalar')->end()
->end()
->end()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider;

use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand Down Expand Up @@ -45,7 +46,10 @@
return 'ldap';
}

/**
* @param ArrayNodeDefinition $node
*/
public function addConfiguration(NodeDefinition $node): void

Check failure on line 52 in src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/LdapFactory.php

View workflow job for this annotation

GitHub Actions / Psalm

MoreSpecificImplementedParamType

src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/LdapFactory.php:52:53: MoreSpecificImplementedParamType: Argument 1 of Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\LdapFactory::addConfiguration has the more specific type 'Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition', expecting 'Symfony\Component\Config\Definition\Builder\NodeDefinition' as defined by Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface::addConfiguration (see https://psalm.dev/140)

Check failure on line 52 in src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/LdapFactory.php

View workflow job for this annotation

GitHub Actions / Psalm

MoreSpecificImplementedParamType

src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/LdapFactory.php:52:53: MoreSpecificImplementedParamType: Argument 1 of Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\LdapFactory::addConfiguration has the more specific type 'Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition', expecting 'Symfony\Component\Config\Definition\Builder\NodeDefinition' as defined by Symfony\Bundle\SecurityBundle\DependencyInjection\Security\UserProvider\UserProviderFactoryInterface::addConfiguration (see https://psalm.dev/140)
{
$node
->children()
Expand All @@ -57,7 +61,7 @@
->prototype('scalar')->end()
->end()
->arrayNode('default_roles', 'default_role')
->beforeNormalization()->ifString()->then(fn ($v) => preg_split('/\s*,\s*/', $v))->end()
->beforeNormalization()->ifString()->then(static fn ($v) => preg_split('/\s*,\s*/', $v))->end()
->requiresAtLeastOneElement()
->prototype('scalar')->end()
->end()
Expand Down
Loading
Loading