8000 Merge branch '5.3' into 5.4 · symfony/symfony@9ccd0ad · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

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 9ccd0ad

Browse files
Merge branch '5.3' into 5.4
* 5.3: Fix KernelBrowser fix [Console] Escape synopsis output Remove hidden dependency on HttpFoundation for SmsBiurasTransport [SecurityBundle] Link UserProviderListener to correct firewall dispatcher Move symfony/runtime from require to require-dev in main composer.json Bump Symfony version to 5.3.2 Update VERSION for 8000 5.3.1 Update CHANGELOG for 5.3.1 [FrameworkBundle] fix KernelBrowser::loginUser with a stateless firewall [HttpFoundation] Add ReturnTypeWillChange to SessionHandlers [Security] Readd deprecated methods to the interfaces remove service if its class doesn't exist Fix not null return from "getCollectionValueTypes" Document null support in NumberToLocalizedStringTransformer Update loader’s directory when calling ContainerConfigurator::withPath
2 parents 2fe4442 + 98777c2 commit 9ccd0ad

File tree

36 files changed

+304
-29
lines changed

36 files changed

+304
-29
lines changed

CHANGELOG-5.3.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ in 5.3 minor versions.
77
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
88
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v5.3.0...v5.3.1
99

10+
* 5.3.1 (2021-06-02)
11+
12+
* bug #41463 [Serializer][Validator] Fix not null return from "getCollectionValueTypes" (jderusse)
13+
* bug #41493 [Security] Readd deprecated methods to the interfaces (wouterj)
14+
* bug #41495 [HttpFoundation] Add ReturnTypeWillChange to SessionHandlers (nikic)
15+
* bug #41485 [HttpKernel] fix ArgumentMetadataFactory messes up controller arguments with attributes (sgehrig)
16+
* bug #41461 Fix Symfony 5.3 end of maintenance date (jmsche)
17+
1018
* 5.3.0 (2021-05-31)
1119

1220
* bug #41458 [FrameworkBundle] fix ConfigBuilderCacheWarmer (nicolas-grekas)

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@
5353
"symfony/polyfill-php73": "^1.11",
5454
"symfony/polyfill-php80": "^1.15",
5555
"symfony/polyfill-php81": "^1.22",
56-
"symfony/polyfill-uuid": "^1.15",
57-
"symfony/runtime": "self.version"
56+
"symfony/polyfill-uuid": "^1.15"
5857
},
5958
"replace": {
6059
"symfony/asset": "self.version",
@@ -144,6 +143,7 @@
144143
"egulias/email-validator": "^2.1.10|^3.1",
145144
"symfony/mercure-bundle": "^0.3",
146145
"symfony/phpunit-bridge": "^5.2|^6.0",
146+
"symfony/runtime": "self.version",
147147
"symfony/security-acl": "~2.8|~3.0",
148148
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
149149
"twig/cssinliner-extra": "^2.12|^3",

src/Symfony/Bridge/Doctrine/Security/User/UserLoaderInterface.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,10 @@
2929
*/
3030
interface UserLoaderInterface
3131
{
32+
/**
33+
* @return UserInterface|null
34+
*
35+
* @deprecated since Symfony 5.3, use loadUserByIdentifier() instead
36+
*/
37+
public function loadUserByUsername(string $username);
3238
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,6 +1450,10 @@ private function registerValidationConfiguration(array $config, ContainerBuilder
14501450
->setArgument(2, $config['not_compromised_password']['enabled'])
14511451
->setArgument(3, $config['not_compromised_password']['endpoint'])
14521452
;
1453+
1454+
if (!class_exists(ExpressionLanguage::class)) {
1455+
$container->removeDefinition('validator.expression_language');
1456+
}
14531457
}
14541458

14551459
private function registerValidatorMapping(ContainerBuilder $container, array $config, array &$files)

src/Symfony/Bundle/FrameworkBundle/KernelBrowser.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,15 @@ public function loginUser($user, string $firewallContext = 'main'): self
122122

123123
$token = new TestBrowserToken($user->getRoles(), $user, $firewallContext);
124124
$token->setAuthenticated(true);
125-
$session = $this->getContainer()->get('test.service_container')->get('session.factory')->createSession();
125+
126+
$container = $this->kernel->getContainer()->get('test.service_container');
127+
$container->get('security.untracked_token_storage')->setToken($token);
128+
129+
if (!$container->has('session') && !$container->has('session_factory')) {
130+
return $this;
131+
}
132+
133+
$session = $container->get($container->has('session') ? 'session' : 'session_factory');
126134
$session->set('_security_'.$firewallContext, serialize($token));
127135
$session->save();
128136

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SecurityTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public function getUsers()
3838
yield ['the-username', ['ROLE_FOO'], null];
3939
yield ['the-username', ['ROLE_FOO'], 'main'];
4040
yield ['other-username', ['ROLE_FOO'], 'custom'];
41+
yield ['stateless-username', ['ROLE_FOO'], 'stateless'];
4142

4243
yield ['the-username', ['ROLE_FOO'], null];
4344
yield ['no-role-username', [], null];

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Security/config.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ security:
2020
memory:
2121
users:
2222
other-username: { password: the-password, roles: ['ROLE_FOO'] }
23+
stateless:
24+
memory:
25+
users:
26+
stateless-username: { password: the-password, roles: ['ROLE_FOO'] }
2327

2428
firewalls:
2529
47C5 main:
@@ -32,6 +36,11 @@ security:
3236
form_login:
3337
check_path: /custom/login/check
3438
provider: custom
39+
stateless:
40+
pattern: ^/stateless
41+
stateless: true
42+
http_basic: ~
43+
provider: stateless
3544

3645
access_control:
3746
- { path: '^/main/user_profile$', roles: IS_AUTHENTICATED_FULLY }

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Security/routing.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ security_profile:
55
security_custom_profile:
66
path: /custom/user_profile
77
defaults: { _controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\SecurityController::profileAction }
8+
9+
security_stateless_profile:
10+
path: /stateless/user_profile
11+
defaults: { _controller: Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\Controller\SecurityController::profileAction }

src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,8 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
367367

368368
$config->replaceArgument(4, $firewall['stateless']);
369369

370+
$firewallEventDispatcherId = 'security.event_dispatcher.'.$id;
371+
370372
// Provider id (must be configured explicitly per firewall/authenticator if more than one provider is set)
371373
$defaultProvider = null;
372374
if (isset($firewall['provider'])) {
@@ -377,7 +379,7 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
377379

378380
if ($this->authenticatorManagerEnabled) {
379381
$container->setDefinition('security.listener.'.$id.'.user_provider', new ChildDefinition('security.listener.user_provider.abstract'))
380-
->addTag('kernel.event_listener', ['event' => CheckPassportEvent::class, 'priority' => 2048, 'method' => 'checkPassport'])
382+
->addTag('kernel.event_listener', ['dispatcher' => $firewallEventDispatcherId, 'event' => CheckPassportEvent::class, 'priority' => 2048, 'method' => 'checkPassport'])
381383
->replaceArgument(0, new Reference($defaultProvider));
382384
}
383385
} elseif (1 === \count($providerIds)) {
@@ -387,7 +389,6 @@ private function createFirewall(ContainerBuilder $container, string $id, array $
387389
$config->replaceArgument(5, $defaultProvider);
388390

389391
// Register Firewall-specific event dispatcher
390-
$firewallEventDispatcherId = 'security.event_dispatcher.'.$id;
391392
$container->register($firewallEventDispatcherId, EventDispatcher::class)
392393
->addTag('event_dispatcher.dispatcher', ['name' => $firewallEventDispatcherId]);
393394

src/Symfony/Bundle/SecurityBundle/Tests/Functional/AuthenticatorTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,28 @@ public function provideEmails()
6363
yield ['jane@example.org', true];
6464
yield ['john@example.org', false];
6565
}
66+
67+
/**
68+
* @dataProvider provideEmailsWithFirewalls
69+
*/
70+
public function testLoginUsersWithMultipleFirewalls(string $username, string $firewallContext)
71+
{
72+
$client = $this->createClient(['test_case' => 'Authenticator', 'root_config' => 'multiple_firewall_user_provider.yml']);
73+
$client->request('GET', '/main/login/check');
74+
75+
$client->request('POST', '/'.$firewallContext.'/login/check', [
76+
'_username' => $username,
77+
'_password' => 'test',
78+
]);
79+
$this->assertResponseRedirects('/'.$firewallContext.'/user_profile');
80+
81+
$client->request('GET', '/'.$firewallContext.'/user_profile');
82+
$this->assertEquals('Welcome '.$username.'!', $client->getResponse()->getContent());
83+
}
84+
85+
public function provideEmailsWithFirewalls()
86+
{
87+
yield ['jane@example.org', 'main'];
88+
yield ['john@example.org', 'custom'];
89+
}
6690
}
Original file line numberDiff line numberDiff line change
@@ -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\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle;
13+
14+
use Symfony\Component\HttpFoundation\RedirectResponse;
15+
use Symfony\Component\HttpFoundation\Request;
16+
use Symfony\Component\HttpFoundation\Response;
17+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
18+
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
19+
use Symfony\Component\Security\Core\Security;
20+
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
21+
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
22+
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
23+
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
24+
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
25+
use Symfony\Component\Security\Http\Util\TargetPathTrait;
26+
27+
class LoginFormAuthenticator extends AbstractLoginFormAuthenticator
28+
{
29+
use TargetPathTrait;
30+
31+
/** @var UrlGeneratorInterface */
32+
private $urlGenerator;
33+
34+
public function __construct(UrlGeneratorInterface $urlGenerator)
35+
{
36+
$this->urlGenerator = $urlGenerator;
37+
}
38+
39+
public function authenticate(Request $request): PassportInterface
40+
{
41+
$username = $request->request->get('_username', '');
42+
43+
$request->getSession()->set(Security::LAST_USERNAME, $username);
44+
45+
return new Passport(
46+
new UserBadge($username),
47+
new PasswordCredentials($request->request->get('_password', '')),
48+
[]
49+
);
50+
}
51+
52+
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $firewallName): ?Response
53+
{
54+
return new RedirectResponse($this->urlGenerator->generate('security_'.$firewallName.'_profile'));
55+
}
56+
57+
protected function getLoginUrl(Request $request): string
58+
{
59+
return strpos($request->getUri(), 'main') ?
60+
$this->urlGenerator->generate('security_main_login') :
61+
$this->urlGenerator->generate('security_custom_login')
62+
;
63+
}
64+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle;
13+
14+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
15+
use Symfony\Component\HttpFoundation\Response;
16+
17+
class SecurityController extends AbstractController
18+
{
19+
public function checkAction()
20+
{
21+
return new Response('OK');
22+
}
23+
24+
public function profileAction()
25+
{
26+
return new Response('Welcome '.$this->getUser()->getUsername().'!');
27+
}
28+
}

src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,12 @@ services:
1414
calls:
1515
- ['setContainer', ['@Psr\Container\ContainerInterface']]
1616
tags: [container.service_subscriber]
17+
Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\SecurityController:
18+
public: true
19+
calls:
20+
- ['setContainer', ['@Psr\Container\ContainerInterface']]
21+
tags: [container.service_subscriber]
1722
Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\ApiAuthenticator: ~
23+
Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\LoginFormAuthenticator:
24+
public: true
25+
arguments: ['@router']
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
imports:
2+
- { resource: ./config.yml }
3+
- { resource: ./security.yml }
4+
5+
security:
6+
firewalls:
7+
main:
8+
pattern: ^/main
9+
provider: in_memory
10+
custom_authenticator: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\LoginFormAuthenticator
11+
custom:
12+
pattern: ^/custom
13+
provider: in_memory2
14+
custom_authenticator: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\LoginFormAuthenticator

src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/Authenticator/routing.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,19 @@ profile:
22
path: /profile
33
defaults:
44
_controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\ProfileController
5+
6+
security_main_login:
7+
path: /main/login/check
8+
defaults: { _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\SecurityController::checkAction }
9+
10+
security_custom_login:
11+
path: /custom/login/check
12+
defaults: { _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\SecurityController::checkAction }
13+
14+
security_main_profile:
15+
path: /main/user_profile
16+
defaults: { _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\SecurityController::profileAction }
17+
18+
security_custom_profile:
19+
path: /custom/user_profile
20+
defaults: { _controller: Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AuthenticatorBundle\SecurityController::profileAction }

src/Symfony/Component/Console/Application.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,7 @@ public function renderThrowable(\Throwable $e, OutputInterface $output): void
798798
$this->doRenderThrowable($e, $output);
799799

800800
if (null !== $this->runningCommand) {
801-
$output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())), OutputInterface::VERBOSITY_QUIET);
801+
$output->writeln(sprintf('<info>%s</info>', OutputFormatter::escape(sprintf($this->runningCommand->getSynopsis(), $this->getName()))), OutputInterface::VERBOSITY_QUIET);
802802
$output->writeln('', OutputInterface::VERBOSITY_QUIET);
803803
}
804804
}

src/Symfony/Component/Console/Tests/ApplicationTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,23 @@ public function testRenderExceptionStackTraceContainsRootException()
927927
$this->assertStringContainsString('Dummy type "class@anonymous" is invalid.', $tester->getDisplay(true));
928928
}
929929

930+
public function testRenderExceptionEscapesLinesOfSynopsis()
931+
{
932+
$application = new Application();
933+
$application->setAutoExit(false);
934+
$application
935+
->register('foo')
936+
->setCode(function () {
937+
throw new \Exception('some exception');
938+
})
939+
->addArgument('info')
940+
;
941+
$tester = new ApplicationTester($application);
942+
943+
$tester->run(['command' => 'foo'], ['decorated' => false]);
944+
$this->assertStringMatchesFormatFile(self::$fixturesPath.'/application_rendersynopsis_escapesline.txt', $tester->getDisplay(true), '->renderException() escapes lines containing formatting of synopsis');
945+
}
946+
930947
public function testRun()
931948
{
932949
$application = new Application();

src/Symfony/Component/Console/Tests/Command/CommandTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ public function testGetSynopsis()
186186
$command = new \TestCommand();
187187
$command->addOption('foo');
188188
$command->addArgument('bar');
189-
$this->assertEquals('namespace:name [--foo] [--] [<bar>]', $command->getSynopsis(), '->getSynopsis() returns the synopsis');
189+
$command->addArgument('info');
190+
$this->assertEquals('namespace:name [--foo] [--] [<bar> [<info>]]', $command->getSynopsis(), '->getSynopsis() returns the synopsis');
190191
}
191192

192193
public function testAddGetUsages()
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
In ApplicationTest.php line %d:
3+
4+
some exception
5+
6+
7+
foo [<info>]

src/Symfony/Component/DependencyInjection/Loader/Configurator/ContainerConfigurator.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ final public function withPath(string $path): self
8989
{
9090
$clone = clone $this;
9191
$clone->path = $clone->file = $path;
92+
$clone->loader->setCurrentDir(\dirname($path));
9293

9394
return $clone;
9495
}

src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public function __construct(?int $scale = 2, ?bool $grouping = true, ?int $round
4545
/**
4646
* Transforms a normalized format into a localized money string.
4747
*
48-
* @param int|float $value Normalized number
48+
* @param int|float|null $value Normalized number
4949
*
5050
* @return string Localized money string
5151
*
@@ -69,7 +69,7 @@ public function transform($value)
6969
*
7070
* @param string $value Localized money string
7171
*
72-
* @return int|float Normalized number
72+
* @return int|float|null Normalized number
7373
*
7474
* @throws TransformationFailedException if the given value is not a string
7575
* or if the value can not be transformed

0 commit comments

Comments
 (0)
0