Merge branch '5.2' into 5.x
* 5.2: Added additional file existence check on temporary file cleanup for dumpFile method fix lexing inline sequences/mappings with trailing whitespaces Added test for issue 39229 Bump Symfony version to 5.2.1 Update VERSION for 5.2.0 Update CHANGELOG for 5.2.0 [Security] [DX] Automatically add PasswordUpgradeBadge + default support() impl in AbstractFormLoginAuthenticator [Console] Enable hyperlinks in Konsole/Yakuake
This commit is contained in:
commit
4f59d2f7c4
@ -7,6 +7,30 @@ in 5.2 minor versions.
|
|||||||
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
|
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
|
||||||
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v5.2.0...v5.2.1
|
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v5.2.0...v5.2.1
|
||||||
|
|
||||||
|
* 5.2.0 (2020-11-30)
|
||||||
|
|
||||||
|
* feature #39213 [Security] [DX] Automatically add PasswordUpgradeBadge + default support() impl in AbstractFormLoginAuthenticator (wouterj)
|
||||||
|
* bug #39166 [Messenger] Fix mssql compatibility for doctrine transport. (bill moll)
|
||||||
|
* bug #39210 [DoctrineBridge] Fix form EntityType with filter on UID (jderusse)
|
||||||
|
* bug #39211 [HttpClient] fix binding to network interfaces (nicolas-grekas)
|
||||||
|
* bug #39129 [DependencyInjection] Fix circular in DI with lazy + byContruct loop (jderusse)
|
||||||
|
* feature #39153 [Security] Automatically register custom authenticator as entry_point (if supported) (wouterj)
|
||||||
|
* bug #39068 [DependencyInjection][Translator] Silent deprecation triggered by libxml_disable_entity_loader (jderusse)
|
||||||
|
* bug #39119 [Form] prevent duplicated error message for file upload limits (xabbuh)
|
||||||
|
* bug #39099 [Form] ignore the pattern attribute for textareas (xabbuh)
|
||||||
|
* feature #39118 [DoctrineBridge] Require doctrine/persistence 2 (greg0ire)
|
||||||
|
* feature #39128 [HttpFoundation] Deprecate BinaryFileResponse::create() (derrabus)
|
||||||
|
* bug #39154 [Yaml] fix lexing strings containing escaped quotation characters (xabbuh)
|
||||||
|
* bug #39187 [Security] Support for SwitchUserToken instances serialized with 4.4/5.1 (derrabus)
|
||||||
|
* bug #39180 [Serializer] Fix denormalizing scalar with UnwrappingDenormalizer (camilledejoye)
|
||||||
|
* bug #38597 [PhpUnitBridge] Fix qualification of deprecations triggered by the debug class loader (fancyweb)
|
||||||
|
* bug #39160 [Console] Use a partial buffer in SymfonyStyle (jderusse)
|
||||||
|
* bug #39168 [Console] Fix console closing tag (jderusse)
|
||||||
|
* bug #39155 [VarDumper] fix casting resources turned into objects on PHP 8 (nicolas-grekas)
|
||||||
|
* bug #39131 [Cache] Fix CI because of Couchbase version (jderusse)
|
||||||
|
* bug #39115 [HttpClient] don't fallback to HTTP/1.1 when HTTP/2 streams break (nicolas-grekas)
|
||||||
|
* bug #33763 [Yaml] fix lexing nested sequences/mappings (xabbuh)
|
||||||
|
|
||||||
* 5.2.0-RC2 (2020-11-21)
|
* 5.2.0-RC2 (2020-11-21)
|
||||||
|
|
||||||
* bug #39113 [DoctrineBridge] drop binary variants of UID types (nicolas-grekas)
|
* bug #39113 [DoctrineBridge] drop binary variants of UID types (nicolas-grekas)
|
||||||
|
@ -95,7 +95,8 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
|
|||||||
public function apply(string $text)
|
public function apply(string $text)
|
||||||
{
|
{
|
||||||
if (null === $this->handlesHrefGracefully) {
|
if (null === $this->handlesHrefGracefully) {
|
||||||
$this->handlesHrefGracefully = 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR') && !getenv('KONSOLE_VERSION');
|
$this->handlesHrefGracefully = 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR')
|
||||||
|
&& (!getenv('KONSOLE_VERSION') || (int) getenv('KONSOLE_VERSION') > 201100);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $this->href && $this->handlesHrefGracefully) {
|
if (null !== $this->href && $this->handlesHrefGracefully) {
|
||||||
|
@ -667,9 +667,11 @@ class Filesystem
|
|||||||
|
|
||||||
$this->rename($tmpFile, $filename, true);
|
$this->rename($tmpFile, $filename, true);
|
||||||
} finally {
|
} finally {
|
||||||
|
if (file_exists($tmpFile)) {
|
||||||
@unlink($tmpFile);
|
@unlink($tmpFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends content to an existing file.
|
* Appends content to an existing file.
|
||||||
|
@ -32,6 +32,20 @@ abstract class AbstractLoginFormAuthenticator extends AbstractAuthenticator impl
|
|||||||
*/
|
*/
|
||||||
abstract protected function getLoginUrl(Request $request): string;
|
abstract protected function getLoginUrl(Request $request): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* Override to change the request conditions that have to be
|
||||||
|
* matched in order to handle the login form submit.
|
||||||
|
*
|
||||||
|
* This default implementation handles all POST requests to the
|
||||||
|
* login path (@see getLoginUrl()).
|
||||||
|
*/
|
||||||
|
public function supports(Request $request): bool
|
||||||
|
{
|
||||||
|
return $request->isMethod('POST') && $this->getLoginUrl($request) === $request->getPathInfo();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override to change what happens after a bad username/password is submitted.
|
* Override to change what happens after a bad username/password is submitted.
|
||||||
*/
|
*/
|
||||||
|
@ -14,6 +14,7 @@ namespace Symfony\Component\Security\Http\EventListener;
|
|||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
|
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
|
||||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PasswordUpgradeBadge;
|
||||||
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials;
|
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials;
|
||||||
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
|
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
|
||||||
use Symfony\Component\Security\Http\Authenticator\Passport\UserPassportInterface;
|
use Symfony\Component\Security\Http\Authenticator\Passport\UserPassportInterface;
|
||||||
@ -65,6 +66,10 @@ class CheckCredentialsListener implements EventSubscriberInterface
|
|||||||
|
|
||||||
$badge->markResolved();
|
$badge->markResolved();
|
||||||
|
|
||||||
|
if (!$passport->hasBadge(PasswordUpgradeBadge::class)) {
|
||||||
|
$passport->addBadge(new PasswordUpgradeBadge($presentedPassword));
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ use Symfony\Component\Security\Core\Encoder\PasswordEncoderInterface;
|
|||||||
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
|
||||||
use Symfony\Component\Security\Core\User\User;
|
use Symfony\Component\Security\Core\User\User;
|
||||||
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
|
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PasswordUpgradeBadge;
|
||||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
||||||
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials;
|
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials;
|
||||||
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
|
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
|
||||||
@ -113,6 +114,54 @@ class CheckCredentialsListenerTest extends TestCase
|
|||||||
$this->listener->checkPassport($event);
|
$this->listener->checkPassport($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testAddsPasswordUpgradeBadge()
|
||||||
|
{
|
||||||
|
$encoder = $this->createMock(PasswordEncoderInterface::class);
|
||||||
|
$encoder->expects($this->any())->method('isPasswordValid')->with('encoded-password', 'ThePa$$word')->willReturn(true);
|
||||||
|
|
||||||
|
$this->encoderFactory->expects($this->any())->method('getEncoder')->with($this->identicalTo($this->user))->willReturn($encoder);
|
||||||
|
|
||||||
|
$passport = new Passport(new UserBadge('wouter', function () { return $this->user; }), new PasswordCredentials('ThePa$$word'));
|
||||||
|
$this->listener->checkPassport($this->createEvent($passport));
|
||||||
|
|
||||||
|
$this->assertTrue($passport->hasBadge(PasswordUpgradeBadge::class));
|
||||||
|
$this->assertEquals('ThePa$$word', $passport->getBadge(PasswordUpgradeBadge::class)->getAndErasePlaintextPassword());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddsNoPasswordUpgradeBadgeIfItAlreadyExists()
|
||||||
|
{
|
||||||
|
$encoder = $this->createMock(PasswordEncoderInterface::class);
|
||||||
|
$encoder->expects($this->any())->method('isPasswordValid')->with('encoded-password', 'ThePa$$word')->willReturn(true);
|
||||||
|
|
||||||
|
$this->encoderFactory->expects($this->any())->method('getEncoder')->with($this->identicalTo($this->user))->willReturn($encoder);
|
||||||
|
|
||||||
|
$passport = $this->getMockBuilder(Passport::class)
|
||||||
|
->setMethods(['addBadge'])
|
||||||
|
->setConstructorArgs([new UserBadge('wouter', function () { return $this->user; }), new PasswordCredentials('ThePa$$word'), [new PasswordUpgradeBadge('ThePa$$word')]])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$passport->expects($this->never())->method('addBadge')->with($this->isInstanceOf(PasswordUpgradeBadge::class));
|
||||||
|
|
||||||
|
$this->listener->checkPassport($this->createEvent($passport));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddsNoPasswordUpgradeBadgeIfPasswordIsInvalid()
|
||||||
|
{
|
||||||
|
$encoder = $this->createMock(PasswordEncoderInterface::class);
|
||||||
|
$encoder->expects($this->any())->method('isPasswordValid')->with('encoded-password', 'ThePa$$word')->willReturn(false);
|
||||||
|
|
||||||
|
$this->encoderFactory->expects($this->any())->method('getEncoder')->with($this->identicalTo($this->user))->willReturn($encoder);
|
||||||
|
|
||||||
|
$passport = $this->getMockBuilder(Passport::class)
|
||||||
|
->setMethods(['addBadge'])
|
||||||
|
->setConstructorArgs([new UserBadge('wouter', function () { return $this->user; }), new PasswordCredentials('ThePa$$word'), [new PasswordUpgradeBadge('ThePa$$word')]])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$passport->expects($this->never())->method('addBadge')->with($this->isInstanceOf(PasswordUpgradeBadge::class));
|
||||||
|
|
||||||
|
$this->listener->checkPassport($this->createEvent($passport));
|
||||||
|
}
|
||||||
|
|
||||||
private function createEvent($passport)
|
private function createEvent($passport)
|
||||||
{
|
{
|
||||||
return new CheckPassportEvent($this->createMock(AuthenticatorInterface::class), $passport);
|
return new CheckPassportEvent($this->createMock(AuthenticatorInterface::class), $passport);
|
||||||
|
@ -435,7 +435,8 @@ class CliDumper extends AbstractDumper
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (null === $this->handlesHrefGracefully) {
|
if (null === $this->handlesHrefGracefully) {
|
||||||
$this->handlesHrefGracefully = 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR') && !getenv('KONSOLE_VERSION');
|
$this->handlesHrefGracefully = 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR')
|
||||||
|
&& (!getenv('KONSOLE_VERSION') || (int) getenv('KONSOLE_VERSION') > 201100);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($attr['ellipsis'], $attr['ellipsis-type'])) {
|
if (isset($attr['ellipsis'], $attr['ellipsis-type'])) {
|
||||||
|
@ -749,11 +749,11 @@ class Parser
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if ('' !== $value && '{' === $value[0]) {
|
if ('' !== $value && '{' === $value[0]) {
|
||||||
$cursor = \strlen($this->currentLine) - \strlen($value);
|
$cursor = \strlen(rtrim($this->currentLine)) - \strlen(rtrim($value));
|
||||||
|
|
||||||
return Inline::parse($this->lexInlineMapping($cursor), $flags, $this->refs);
|
return Inline::parse($this->lexInlineMapping($cursor), $flags, $this->refs);
|
||||||
} elseif ('' !== $value && '[' === $value[0]) {
|
} elseif ('' !== $value && '[' === $value[0]) {
|
||||||
$cursor = \strlen($this->currentLine) - \strlen($value);
|
$cursor = \strlen(rtrim($this->currentLine)) - \strlen(rtrim($value));
|
||||||
|
|
||||||
return Inline::parse($this->lexInlineSequence($cursor), $flags, $this->refs);
|
return Inline::parse($this->lexInlineSequence($cursor), $flags, $this->refs);
|
||||||
}
|
}
|
||||||
|
@ -2670,6 +2670,29 @@ YAML;
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMultipleWhitespaceAtEndOfLine()
|
||||||
|
{
|
||||||
|
$yaml = "\nfoo:\n arguments: [ '@bar' ] \n";
|
||||||
|
$this->assertSame(
|
||||||
|
[
|
||||||
|
'foo' => [
|
||||||
|
'arguments' => ['@bar'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
$this->parser->parse($yaml)
|
||||||
|
);
|
||||||
|
|
||||||
|
$yaml = "\nfoo:\n bar: {} \n";
|
||||||
|
$this->assertSame(
|
||||||
|
[
|
||||||
|
'foo' => [
|
||||||
|
'bar' => [],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
$this->parser->parse($yaml)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a regression test for a bug where a YAML block with a nested multiline string using | was parsed without
|
* This is a regression test for a bug where a YAML block with a nested multiline string using | was parsed without
|
||||||
* a trailing \n when a shorter YAML document was parsed before.
|
* a trailing \n when a shorter YAML document was parsed before.
|
||||||
|
Reference in New Issue
Block a user