8000 Merge branch '5.2' into 5.x · symfony/symfony@78fccbe · GitHub
[go: up one dir, main page]

Skip to content

Commit 78fccbe

Browse files
Merge branch '5.2' into 5.x
* 5.2: [Console] Fix line wrapping for decorated text in block output [Inflector] Fixed pluralize "coupon" [PhpUnitBridge] fix compat with symfony/debug [VarDumper] Adds support for ReflectionUnionType to VarDumper Correctly clear lines for multi-line progress bar messages. [Security] Add XML support for authenticator manager
2 parents 692c629 + 98fce3e commit 78fccbe

File tree

21 files changed

+365
-48
lines changed

21 files changed

+365
-48
lines changed

src/Symfony/Bridge/PhpUnit/DeprecationErrorHandler/Deprecation.php

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Bridge\PhpUnit\DeprecationErrorHandler;
1313

14+
use PHPUnit\Framework\TestCase;
15+
use PHPUnit\Framework\TestSuite;
1416
use PHPUnit\Util\Test;
1517
use Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerFor;
1618
use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader;
@@ -87,41 +89,45 @@ public function __construct($message, array $trace, $file)
8789
}
8890
}
8991

90-
if (isset($line['object']) || isset($line['class'])) {
91-
set_error_handler(function () {});
92-
$parsedMsg = unserialize($this->message);
93-
restore_error_handler();
94-
if ($parsedMsg && isset($parsedMsg['deprecation'])) {
95-
$this->message = $parsedMsg['deprecation'];
96-
$this->originClass = $parsedMsg['class'];
97-
$this->originMethod = $parsedMsg['method'];
98-
if (isset($parsedMsg['files_stack'])) {
99-
$this->originalFilesStack = $parsedMsg['files_stack'];
100-
}
101-
// If the deprecation has been triggered via
102-
// \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest()
103-
// then we need to use the serialized information to determine
104-
// if the error has been triggered from vendor code.
105-
if (isset($parsedMsg['triggering_file'])) 10000 {
106-
$this->triggeringFile = $parsedMsg['triggering_file'];
107-
}
92+
if (!isset($line['object']) && !isset($line['class'])) {
93+
return;
94+
}
10895

109-
return;
96+
set_error_handler(function () {});
97+
$parsedMsg = unserialize($this->message);
98+
restore_error_handler();
99+
if ($parsedMsg && isset($parsedMsg['deprecation'])) {
100+
$this->message = $parsedMsg['deprecation'];
101+
$this->originClass = $parsedMsg['class'];
102+
$this->originMethod = $parsedMsg['method'];
103+
if (isset($parsedMsg['files_stack'])) {
104+
$this->originalFilesStack = $parsedMsg['files_stack'];
110105
}
106+
// If the deprecation has been triggered via
107+
// \Symfony\Bridge\PhpUnit\Legacy\SymfonyTestsListenerTrait::endTest()
108+
// then we need to use the serialized information to determine
109+
// if the error has been triggered from vendor code.
110+
if (isset($parsedMsg['triggering_file'])) {
111+
$this->triggeringFile = $parsedMsg['triggering_file'];
112+
}
113+
114+
return;
115+
}
111116

112-
if (!isset($line['class'], $trace[$i - 2]['function']) || 0 !== strpos($line['class'], SymfonyTestsListenerFor::class)) {
113-
$this->originClass = isset($line['object']) ? \get_class($line['object']) : $line['class'];
114-
$this->originMethod = $line['function'];
117+
if (!isset($line['class'], $trace[$i - 2]['function']) || 0 !== strpos($line['class'], SymfonyTestsListenerFor::class)) {
118+
$this->originClass = isset($line['object']) ? \get_class($line['object']) : $line['class'];
119+
$this->originMethod = $line['function'];
115120

116-
return;
117-
}
121+
return;
122+
}
118123

119-
if ('trigger_error' !== $trace[$i - 2]['function'] || isset($trace[$i - 2]['class'])) {
120-
$this->originClass = \get_class($line['args'][0]);
121-
$this->originMethod = $line['args'][0]->getName();
124+
$test = $line['args'][0] ?? null;
122125

123-
return;
124-
}
126+
if (($test instanceof TestCase || $test instanceof TestSuite) && ('trigger_error' !== $trace[$i - 2]['function'] || isset($trace[$i - 2]['class']))) {
127+
$this->originClass = \get_class($line['args'][0]);
128+
$this->originMethod = $line['args'][0]->getName();
129+
130+
return;
125131
}
126132
}
127133

src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/LoginLinkFactory.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class LoginLinkFactory extends AbstractFactory implements AuthenticatorFactoryIn
3131
public function addConfiguration(NodeDefinition $node)
3232
{
3333
/** @var NodeBuilder $builder */
34-
$builder = $node->children();
34+
$builder = $node->fixXmlConfig('signature_property', 'signature_properties')->children();
3535

3636
$builder
3737
->scalarNode('check_route')
@@ -98,6 +98,10 @@ public function createAuthenticator(ContainerBuilder $container, string $firewal
9898

9999
if (null !== $config['max_uses'] && !isset($config['used_link_cache'])) {
100100
$config['used_link_cache'] = 'security.authenticator.cache.expired_links';
101+
$defaultCacheDefinition = $container->getDefinition($config['used_link_cache']);
102+
if (!$defaultCacheDefinition->hasTag('cache.pool')) {
103+
$defaultCacheDefinition->addTag('cache.pool');
104+
}
101105
}
102106

103107
$expiredStorageId = null;

src/Symfony/Bundle/SecurityBundle/Resources/config/schema/security-1.0.xsd

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
<xsd:attribute name="hide-user-not-found" type="xsd:boolean" />
2626
<xsd:attribute name="always-authenticate-before-granting" type="xsd:boolean" />
2727
<xsd:attribute name="erase-credentials" type="xsd:boolean" />
28+
<xsd:attribute name="enable-authenticator-manager" type="xsd:boolean" />
2829
</xsd:complexType>
2930

3031
<xsd:complexType name="encoders">
@@ -166,6 +167,7 @@
166167
<xsd:element name="http-basic-ldap" type="http_basic_ldap" minOccurs="0" maxOccurs="1" />
167168
<xsd:element name="json-login" type="json_login" minOccurs="0" maxOccurs="1" />
168169
<xsd:element name="json-login-ldap" type="json_login_ldap" minOccurs="0" maxOccurs="1" />
170+
<xsd:element name="login-throttling" type="login_throttling" minOccurs="0" maxOccurs="1" />
169171
<xsd:element name="remember-me" type="remember_me" minOccurs="0" maxOccurs="1" />
170172
<xsd:element name="remote-user" type="remote_user" minOccurs="0" maxOccurs="1" />
171173
<xsd:element name="x509" type="x509" minOccurs="0" maxOccurs="1" />
@@ -185,6 +187,7 @@
185187
<xsd:attribute name="provider" type="xsd:string" />
186188
<xsd:attribute name="stateless" type="xsd:boolean" />
187189
<xsd:attribute name="context" type="xsd:string" />
190+
<xsd:attribute name="lazy" type="xsd:boolean" />
188191
<!-- allow factories to use dynamic elements -->
189192
<xsd:anyAttribute processContents="lax" />
190193
</xsd:complexType>
@@ -256,6 +259,7 @@
256259
<xsd:attribute name="csrf-token-id" type="xsd:string" />
257260
<xsd:attribute name="post-only" type="xsd:boolean" />
258261
<xsd:attribute name="csrf-token-generator" type="xsd:string" />
262+
<xsd:attribute name="enable-csrf" type="xsd:boolean" />
259263
<xsd:attributeGroup ref="success-handler-options" />
260264
<xsd:attributeGroup ref="failure-handler-options" />
261265
</xsd:extension>
@@ -308,6 +312,25 @@
308312
</xsd:complexContent>
309313
</xsd:complexType>
310314

315+
<xsd:complexType name="login_link">
316+
<xsd:choice minOccurs="0" maxOccurs="unbounded">
317+
<xsd:element name="signature-property" type="xsd:string" />
318+
</xsd:choice>
319+
<xsd:attribute name="check-route" type="xsd:string" />
320+
<xsd:attribute name="check-post-only" type="xsd:boolean" />
321+
<xsd:attribute name="lifetime" type="xsd:integer" />
322+
<xsd:attribute name="max-uses" type="xsd:integer" />
323+
<xsd:attribute name="used-link-cache" type="xsd:string" />
324+
<xsd:attribute name="success-handler" type="xsd:string" />
325+
<xsd:attribute name="failure-handler" type="xsd:string" />
326+
<xsd:attribute name="provider" type="xsd:string" />
327+
</xsd:complexType>
328+
329+
<xsd:complexType name="login_throttling">
330+
<xsd:attribute name="limiter" type="xsd:string" />
331+
<xsd:attribute name="max-attempts" type="xsd:integer" />
332+
</xsd:complexType>
333+
311334
<xsd:complexType name="remember_me">
312335
<xsd:choice minOccurs="0" maxOccurs="unbounded">
313336
<xsd:element name="user-provider" type="xsd:string" />

src/Symfony/Bundle/SecurityBundle/Resources/config/security_authenticator_login_link.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
->set('security.authenticator.cache.expired_links')
5252
->parent('cache.app')
5353
->private()
54-
->tag('cache.pool')
5554

5655
->set('security.authenticator.firewall_aware_login_link_handler', FirewallAwareLoginLinkHandler::class)
5756
->args([

src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,46 @@
2525
use Symfony\Component\Security\Core\Authorization\AccessDecisionManager;
2626
use Symfony\Component\Security\Core\Encoder\NativePasswordEncoder;
2727
use Symfony\Component\Security\Core\Encoder\SodiumPasswordEncoder;
28+
use Symfony\Component\Security\Http\Authentication\AuthenticatorManager;
2829

2930
abstract class CompleteConfigurationTest extends TestCase
3031
{
3132
abstract protected function getLoader(ContainerBuilder $container);
3233

3334
abstract protected function getFileExtension();
3435

36+
public function testAuthenticatorManager()
37+
{
38+
$container = $this->getContainer('authenticator_manager');
39+
40+
$this->assertEquals(AuthenticatorManager::class, $container->getDefinition('security.authenticator.manager.main')->getClass());
41+
42+
// login link
43+
$expiredStorage = $container->getDefinition($expiredStorageId = 'security.authenticator.expired_login_link_storage.main');
44+
$this->assertEquals('cache.redis', (string) $expiredStorage->getArgument(0));
45+
$this->assertEquals(3600, (string) $expiredStorage->getArgument(1));
46+
47+
$linker = $container->getDefinition($linkerId = 'security.authenticator.login_link_handler.main');
48+
$this->assertEquals(['id', 'email'], $linker->getArgument(3));
49+
$this->assertEquals([
50+
'route_name' => 'login_check',
51+
'lifetime' => 3600,
52+
'max_uses' => 1,
53+
], $linker->getArgument(5));
54+
$this->assertEquals($expiredStorageId, (string) $linker->getArgument(6));
55+
56+
$authenticator = $container->getDefinition('security.authenticator.login_link.main');
57+
$this->assertEquals($linkerId, (string) $authenticator->getArgument(0));
58+
$this->assertEquals([
59+
'check_route' => 'login_check',
60+
'check_post_only' => true,
61+
], $authenticator->getArgument(4));
62+
63+
// login throttling
64+
$listener = $container->getDefinition('security.listener.login_throttling.main');
65+
$this->assertEquals('app.rate_limiter', (string) $listener->getArgument(1));
66+
}
67+
3568
public function testRolesHierarchy()
3669
{
3770
$container = $this->getContainer('container1');
@@ -940,6 +973,7 @@ protected function getContainer($file)
940973
$container->setParameter('kernel.debug', false);
941974
$container->setParameter('request_listener.http_port', 80);
942975
$container->setParameter('request_listener.https_port', 443);
976+
$container->register('cache.app', \stdClass::class);
943977

944978
$security = new SecurityExtension();
945979
$container->registerExtension($security);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
$container->loadFromExtension('security', [
4+
'enable_authenticator_manager' => true,
5+
'firewalls' => [
6+
'main' => [
7+
'login_link' => [
8+
'check_route' => 'login_check',
9+
'check_post_only' => true,
10+
'signature_properties' => ['id', 'email'],
11+
'max_uses' => 1,
12+
'lifetime' => 3600,
13+
'used_link_cache' => 'cache.redis',
14+
],
15+
'login_throttling' => [
16+
'limiter' => 'app.rate_limiter',
17+
],
18+
],
19+
],
20+
]);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<srv:container xmlns="http://symfony.com/schema/dic/security"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:srv="http://symfony.com/schema/dic/services"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services
6+
https://symfony.com/schema/dic/services/services-1.0.xsd
7+
http://symfony.com/schema/dic/security
8+
https://symfony.com/schema/dic/security/security-1.0.xsd">
9+
10+
<config enable-authenticator-manager="true">
11+
<firewall name="main">
12+
<login-link check-route="login_check"
13+
check-post-only="true"
14+
max-uses="1"
15+
lifetime="3600"
16+
used-link-cache="cache.redis"
17+
>
18+
<signature-property>id</signature-property>
19+
<signature-property>email</signature-property>
20+
</login-link>
21+
<login-throttling limiter="app.rate_limiter"/>
22+
</firewall>
23+
</config>
24+
</srv:container>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
security:
2+
enable_authenticator_manager: true
3+
firewalls:
4+
main:
5+
login_link:
6+
check_route: login_check
7+
check_post_only: true
8+
signature_properties: [id, email]
9+
max_uses: 1
10+
lifetime: 3600
11+
used_link_cache: 'cache.redis'
12+
login_throttling:
13+
limiter: 'app.rate_limiter'

src/Symfony/Component/Console/Helper/ProgressBar.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,8 +472,15 @@ private function overwrite(string $message): void
472472
if ($this->overwrite) {
473473
if (null !== $this->previousMessage) {
474474
if ($this->output instanceof ConsoleSectionOutput) {
475-
$lines = floor(Helper::strlenWithoutDecoration($this->output->getFormatter(), $message) / $this->terminal->getWidth()) + $this->formatLineCount + 1;
476-
$this->output->clear($lines);
475+
$messageLines = explode("\n", $message);
476+
$lineCount = \count($messageLines);
477+
foreach ($messageLines as $messageLine) {
478+
$messageLineLength = Helper::strlenWithoutDecoration($this->output->getFormatter(), $messageLine);
479+
if ($messageLineLength > $this->terminal->getWidth()) {
480+
$lineCount += floor($messageLineLength / $this->terminal->getWidth());
481+
}
482+
}
483+
$this->output->clear($lineCount);
477484
} else {
478485
if ($this->formatLineCount > 0) {
479486
$this->cursor->moveUp($this->formatLineCount);

src/Symfony/Component/Console/Style/SymfonyStyle.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,12 @@ private function createBlock(iterable $messages, string $type = null, string $st
476476
$message = OutputFormatter::escape($message);
477477
}
478478

479-
$lines = array_merge($lines, explode(\PHP_EOL, wordwrap($message, $this->lineLength - $prefixLength - $indentLength, \PHP_EOL, true)));
479+
$decorationLength = Helper::strlen($message) - Helper::strlenWithoutDecoration($this->getFormatter(), $message);
480+
$messageLineLength = min($this->lineLength - $prefixLength - $indentLength + $decorationLength, $this->lineLength);
481+
$messageLines = explode(\PHP_EOL, wordwrap($message, $messageLineLength, \PHP_EOL, true));
482+
foreach ($messageLines as $messageLine) {
483+
$lines[] = $messageLine;
484+
}
480485

481486
if (\count($messages) > 1 && $key < \count($messages) - 1) {
482487
$lines[] = '';
@@ -496,7 +501,9 @@ private function createBlock(iterable $messages, string $type = null, string $st
496501
}
497502

498503
$line = $prefix.$line;
499-
$line .= str_repeat(' ', $this->lineLength - Helper::strlenWithoutDecoration($this->getFormatter(), $line));
504+
$decorationLength = Helper::strlen($line) - Helper::strlenWithoutDecoration($this->getFormatter(), $line);
505+
$messageLineLength = min($this->lineLength - $prefixLength - $indentLength + $decorationLength, $this->lineLength);
506+
$line .= str_repeat(' ', max($this->lineLength - Helper::strlenWithoutDecoration($this->getFormatter(), $line), 0));
500507

501508
if ($style) {
502509
$line = sprintf('<%s>%s</>', $style, $line);
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

2-
 // Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et 
3-
 // dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea 
4-
 // commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla 
5-
 // pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim
6-
 // id est laborum
2+
 // Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore 
3+
 // magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo 
4+
 // consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla 
5+
 // pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
6+
 // est laborum
77

0 commit comments

Comments
 (0)
0