Skip to content

Commit 6c44684

Browse files
committed
Merge branch '7.0' into 7.1
* 7.0: fix used class after merge fix tests [Console] Only execute additional checks for color support if the output is a TTY fix aircraft inflection [TwigBundle] Fix configuration when 'paths' is null Fix AttributeClassLoaderTestCase + Added ->setUp() - Removed 'abstract' so it'd be picked up by Tests. * Changed getNamespace() to full path Qualified Name. * Rename file AttributeClassLoaderTestCase to AttributeClassLoaderTest and the class. register the MailPaceTransportFactory [String] Correct inflection of axis [Security] Fix `AuthenticationUtils::getLastUsername()` returning null [Process] Fixed inconsistent test fix(ldap): replace {username} with {user_identifier} in LDAP factories
2 parents 052c2c9 + 9a38e81 commit 6c44684

File tree

14 files changed

+209
-20
lines changed

14 files changed

+209
-20
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public function addConfiguration(NodeDefinition $node): void
3232
$node
3333
->children()
3434
->scalarNode('service')->defaultValue('ldap')->end()
35-
->scalarNode('dn_string')->defaultValue('{username}')->end()
35+
->scalarNode('dn_string')->defaultValue('{user_identifier}')->end()
3636
->scalarNode('query_string')->end()
3737
->scalarNode('search_dn')->defaultValue('')->end()
3838
->scalarNode('search_password')->defaultValue('')->end()

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public function addConfiguration(NodeDefinition $node): void
7777
$node
7878
->children()
7979
->scalarNode('service')->defaultValue('ldap')->end()
80-
->scalarNode('dn_string')->defaultValue('{username}')->end()
80+
->scalarNode('dn_string')->defaultValue('{user_identifier}')->end()
8181
->scalarNode('query_string')->end()
8282
->scalarNode('search_dn')->defaultValue('')->end()
8383
->scalarNode('search_password')->defaultValue('')->end()

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function addConfiguration(NodeDefinition $node): void
2929
$node
3030
->children()
3131
->scalarNode('service')->defaultValue('ldap')->end()
32-
->scalarNode('dn_string')->defaultValue('{username}')->end()
32+
->scalarNode('dn_string')->defaultValue('{user_identifier}')->end()
3333
->scalarNode('query_string')->end()
3434
->scalarNode('search_dn')->defaultValue('')->end()
3535
->scalarNode('search_password')->defaultValue('')->end()

src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/UserProvider/LdapFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public function addConfiguration(NodeDefinition $node): void
6464
->prototype('scalar')->end()
6565
->end()
6666
->scalarNode('uid_key')->defaultValue('sAMAccountName')->end()
67-
->scalarNode('filter')->defaultValue('({uid_key}={username})')->end()
67+
->scalarNode('filter')->defaultValue('({uid_key}={user_identifier})')->end()
6868
->scalarNode('password_attribute')->defaultNull()->end()
6969
->end()
7070
;

src/Symfony/Bundle/TwigBundle/DependencyInjection/Configuration.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ private function addTwigOptions(ArrayNodeDefinition $rootNode): void
153153
->normalizeKeys(false)
154154
->useAttributeAsKey('paths')
155155
->beforeNormalization()
156-
->always()
156+
->ifArray()
157157
->then(function ($paths) {
158158
$normalized = [];
159159
foreach ($paths as $path => $namespace) {

src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,16 @@ public function testArrayKeysInGlobalsAreNotNormalized()
5252

5353
$this->assertSame(['global' => ['value' => ['some-key' => 'some-value']]], $config['globals']);
5454
}
55+
56+
public function testNullPathsAreConvertedToIterable()
57+
{
58+
$input = [
59+
'paths' => null,
60+
];
61+
62+
$processor = new Processor();
63+
$config = $processor->processConfiguration(new Configuration(), [$input]);
64+
65+
$this->assertSame([], $config['paths']);
66+
}
5567
}

src/Symfony/Component/Console/Output/StreamOutput.php

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ protected function hasColorSupport(): bool
9494
return false;
9595
}
9696

97+
if (!$this->isTty()) {
98+
return false;
99+
}
100+
97101
if (\DIRECTORY_SEPARATOR === '\\'
98102
&& \function_exists('sapi_windows_vt100_support')
99103
&& @sapi_windows_vt100_support($this->stream)
@@ -104,7 +108,36 @@ protected function hasColorSupport(): bool
104108
return 'Hyper' === getenv('TERM_PROGRAM')
105109
|| false !== getenv('ANSICON')
106110
|| 'ON' === getenv('ConEmuANSI')
107-
|| str_starts_with((string) getenv('TERM'), 'xterm')
108-
|| stream_isatty($this->stream);
111+
|| str_starts_with((string) getenv('TERM'), 'xterm');
112+
}
113+
114+
/**
115+
* Checks if the stream is a TTY, i.e; whether the output stream is connected to a terminal.
116+
*
117+
* Reference: Composer\Util\Platform::isTty
118+
* https://github.com/composer/composer
119+
*/
120+
private function isTty(): bool
121+
{
122+
// Detect msysgit/mingw and assume this is a tty because detection
123+
// does not work correctly, see https://github.com/composer/composer/issues/9690
124+
if (\in_array(strtoupper((string) getenv('MSYSTEM')), ['MINGW32', 'MINGW64'], true)) {
125+
return true;
126+
}
127+
128+
// Modern cross-platform function, includes the fstat fallback so if it is present we trust it
129+
if (\function_exists('stream_isatty')) {
130+
return stream_isatty($this->stream);
131+
}
132+
133+
// Only trusting this if it is positive, otherwise prefer fstat fallback.
134+
if (\function_exists('posix_isatty') && posix_isatty($this->stream)) {
135+
return true;
136+
}
137+
138+
$stat = @fstat($this->stream);
139+
140+
// Check if formatted mode is S_IFCHR
141+
return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
109142
}
110143
}

src/Symfony/Component/Mailer/Transport.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\Mailer\Bridge\MailerSend\Transport\MailerSendTransportFactory;
2323
use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunTransportFactory;
2424
use Symfony\Component\Mailer\Bridge\Mailjet\Transport\MailjetTransportFactory;
25+
use Symfony\Component\Mailer\Bridge\MailPace\Transport\MailPaceTransportFactory;
2526
use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkTransportFactory;
2627
use Symfony\Component\Mailer\Bridge\Resend\Transport\ResendTransportFactory;
2728
use Symfony\Component\Mailer\Bridge\Scaleway\Transport\ScalewayTransportFactory;
@@ -54,6 +55,7 @@ final class Transport
5455
MailerSendTransportFactory::class,
5556
MailgunTransportFactory::class,
5657
MailjetTransportFactory::class,
58+
MailPaceTransportFactory::class,
5759
MandrillTransportFactory::class,
5860
PostmarkTransportFactory::class,
5961
ResendTransportFactory::class,

src/Symfony/Component/Process/Tests/ErrorProcessInitiator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
while (!str_contains($process->getOutput(), 'ready')) {
2626
usleep(1000);
2727
}
28-
$process->signal(\SIGSTOP);
28+
$process->isRunning() && $process->signal(\SIGSTOP);
2929
$process->wait();
3030

3131
return $process->getExitCode();

src/Symfony/Component/Routing/Tests/Loader/AttributeClassLoaderTestCase.php renamed to src/Symfony/Component/Routing/Tests/Loader/AttributeClassLoaderTest.php

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Routing\Alias;
16-
use Symfony\Component\Routing\Loader\AttributeClassLoader;
1716
use Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\AbstractClassController;
1817
use Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\ActionPathController;
1918
use Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\BazClass;
@@ -40,10 +39,18 @@
4039
use Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\RouteWithEnv;
4140
use Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\RouteWithPrefixController;
4241
use Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\Utf8ActionControllers;
42+
use Symfony\Component\Routing\Tests\Fixtures\TraceableAttributeClassLoader;
4343

44-
abstract class AttributeClassLoaderTestCase extends TestCase
44+
class AttributeClassLoaderTest extends TestCase
4545
{
46-
protected AttributeClassLoader $loader;
46+
protected TraceableAttributeClassLoader $loader;
47+
48+
protected function setUp(string $env = null): void
49+
{
50+
parent::setUp();
51+
52+
$this->loader = new TraceableAttributeClassLoader($env);
53+
}
4754

4855
/**
4956
* @dataProvider provideTestSupportsChecksResource
@@ -77,7 +84,7 @@ public function testSimplePathRoute()
7784
$routes = $this->loader->load(ActionPathController::class);
7885
$this->assertCount(1, $routes);
7986
$this->assertEquals('/path', $routes->get('action')->getPath());
80-
$this->assertEquals(new Alias('action'), $routes->getAlias('Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures' .'\ActionPathController::action'));
87+
$this->assertEquals(new Alias('action'), $routes->getAlias('Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\ActionPathController::action'));
8188
}
8289

8390
public function testRequirementsWithoutPlaceholderName()
@@ -101,11 +108,11 @@ public function testInvokableControllerLoader()
101108

102109
public function testInvokableFQCNAliasConflictController()
103110
{
104-
$routes = $this->loader->load($this->getNamespace().'\InvokableFQCNAliasConflictController');
111+
$routes = $this->loader->load('Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\InvokableFQCNAliasConflictController');
105112
$this->assertCount(1, $routes);
106-
$this->assertEquals('/foobarccc', $routes->get($this->getNamespace().'\InvokableFQCNAliasConflictController')->getPath());
107-
$this->assertNull($routes->getAlias($this->getNamespace().'\InvokableFQCNAliasConflictController'));
108-
$this->assertEquals(new Alias($this->getNamespace().'\InvokableFQCNAliasConflictController'), $routes->getAlias($this->getNamespace().'\InvokableFQCNAliasConflictController::__invoke'));
113+
$this->assertEquals('/foobarccc', $routes->get('Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\InvokableFQCNAliasConflictController')->getPath());
114+
$this->assertNull($routes->getAlias('Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\InvokableFQCNAliasConflictController'));
115+
$this->assertEquals(new Alias('Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\InvokableFQCNAliasConflictController'), $routes->getAlias('Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\InvokableFQCNAliasConflictController::__invoke'));
109116
}
110117

111118
public function testInvokableMethodControllerLoader()
@@ -164,8 +171,8 @@ public function testMethodActionControllers()
164171
$this->assertSame(['put', 'post'], array_keys($routes->all()));
165172
$this->assertEquals('/the/path', $routes->get('put')->getPath());
166173
$this->assertEquals('/the/path', $routes->get('post')->getPath());
167-
$this->assertEquals(new Alias('post'), $routes->getAlias('Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures' .'\MethodActionControllers::post'));
168-
$this->assertEquals(new Alias('put'), $routes->getAlias('Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures' .'\MethodActionControllers::put'));
174+
$this->assertEquals(new Alias('post'), $routes->getAlias('Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\MethodActionControllers::post'));
175+
$this->assertEquals(new Alias('put'), $routes->getAlias('Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\MethodActionControllers::put'));
169176
}
170177

171178
public function testInvokableClassRouteLoadWithMethodAnnotation()

src/Symfony/Component/Security/Http/Authentication/AuthenticationUtils.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ public function getLastUsername(): string
5353
$request = $this->getRequest();
5454

5555
if ($request->attributes->has(SecurityRequestAttributes::LAST_USERNAME)) {
56-
return $request->attributes->get(SecurityRequestAttributes::LAST_USERNAME, '');
56+
return $request->attributes->get(SecurityRequestAttributes::LAST_USERNAME) ?? '';
5757
}
5858

59-
return $request->hasSession() ? $request->getSession()->get(SecurityRequestAttributes::LAST_USERNAME, '') : '';
59+
return $request->hasSession() ? ($request->getSession()->get(SecurityRequestAttributes::LAST_USERNAME) ?? '') : '';
6060
}
6161

6262
/**
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
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\Component\Security\Http\Tests\Authentication;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\HttpFoundation\Request;
16+
use Symfony\Component\HttpFoundation\RequestStack;
17+
use Symfony\Component\HttpFoundation\Session\Session;
18+
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
19+
use Symfony\Component\Security\Core\Exception\AuthenticationException;
20+
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
21+
use Symfony\Component\Security\Http\SecurityRequestAttributes;
22+
23+
class AuthenticationUtilsTest extends TestCase
24+
{
25+
public function testLastAuthenticationErrorWhenRequestHasAttribute()
26+
{
27+
$authenticationError = new AuthenticationException();
28+
$request = Request::create('/');
29+
$request->attributes->set(SecurityRequestAttributes::AUTHENTICATION_ERROR, $authenticationError);
30+
31+
$requestStack = new RequestStack();
32+
$requestStack->push($request);
33+
34+
$utils = new AuthenticationUtils($requestStack);
35+
$this->assertSame($authenticationError, $utils->getLastAuthenticationError());
36+
}
37+
38+
public function testLastAuthenticationErrorInSession()
39+
{
40+
$authenticationError = new AuthenticationException();
41+
42+
$request = Request::create('/');
43+
44+
$session = new Session(new MockArraySessionStorage());
45+
$session->set(SecurityRequestAttributes::AUTHENTICATION_ERROR, $authenticationError);
46+
$request->setSession($session);
47+
48+
$requestStack = new RequestStack();
49+
$requestStack->push($request);
50+
51+
$utils = new AuthenticationUtils($requestStack);
52+
$this->assertSame($authenticationError, $utils->getLastAuthenticationError());
53+
$this->assertFalse($session->has(SecurityRequestAttributes::AUTHENTICATION_ERROR));
54+
}
55+
56+
public function testLastAuthenticationErrorInSessionWithoutClearing()
57+
{
58+
$authenticationError = new AuthenticationException();
59+
60+
$request = Request::create('/');
61+
62+
$session = new Session(new MockArraySessionStorage());
63+
$session->set(SecurityRequestAttributes::AUTHENTICATION_ERROR, $authenticationError);
64+
$request->setSession($session);
65+
66+
$requestStack = new RequestStack();
67+
$requestStack->push($request);
68+
69+
$utils = new AuthenticationUtils($requestStack);
70+
$this->assertSame($authenticationError, $utils->getLastAuthenticationError(false));
71+
$this->assertTrue($session->has(SecurityRequestAttributes::AUTHENTICATION_ERROR));
72+
}
73+
74+
public function testLastUserNameIsDefinedButNull()
75+
{
76+
$request = Request::create('/');
77+
$request->attributes->set(SecurityRequestAttributes::LAST_USERNAME, null);
78+
79+
$requestStack = new RequestStack();
80+
$requestStack->push($request);
81+
82+
$utils = new AuthenticationUtils($requestStack);
83+
$this->assertSame('', $utils->getLastUsername());
84+
}
85+
86+
public function testLastUserNameIsDefined()
87+
{
88+
$request = Request::create('/');
89+
$request->attributes->set(SecurityRequestAttributes::LAST_USERNAME, 'user');
90+
91+
$requestStack = new RequestStack();
92+
$requestStack->push($request);
93+
94+
$utils = new AuthenticationUtils($requestStack);
95+
$this->assertSame('user', $utils->getLastUsername());
96+
}
97+
98+
public function testLastUserNameIsDefinedInSessionButNull()
99+
{
100+
$request = Request::create('/');
101+
102+
$session = new Session(new MockArraySessionStorage());
103+
$session->set(SecurityRequestAttributes::LAST_USERNAME, null);
104+
$request->setSession($session);
105+
106+
$requestStack = new RequestStack();
107+
$requestStack->push($request);
108+
109+
$utils = new AuthenticationUtils($requestStack);
110+
$this->assertSame('', $utils->getLastUsername());
111+
}
112+
113+
public function testLastUserNameIsDefinedInSession()
114+
{
115+
$request = Request::create('/');
116+
117+
$session = new Session(new MockArraySessionStorage());
118+
$session->set(SecurityRequestAttributes::LAST_USERNAME, 'user');
119+
$request->setSession($session);
120+
121+
$requestStack = new RequestStack();
122+
$requestStack->push($request);
123+
124+
$utils = new AuthenticationUtils($requestStack);
125+
$this->assertSame('user', $utils->getLastUsername());
126+
}
127+
}

src/Symfony/Component/String/Inflector/EnglishInflector.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ final class EnglishInflector implements InflectorInterface
166166
// Fourth entry: Whether the suffix may succeed a consonant
167167
// Fifth entry: plural suffix, normal
168168

169+
// axes (axis)
170+
['sixa', 4, false, false, 'axes'],
171+
169172
// criterion (criteria)
170173
['airetirc', 8, false, false, 'criterion'],
171174

@@ -384,6 +387,9 @@ final class EnglishInflector implements InflectorInterface
384387

385388
// traffic
386389
'ciffart',
390+
391+
// aircraft
392+
'tfarcria',
387393
];
388394

389395
public function singularize(string $plural): array

src/Symfony/Component/String/Tests/Inflector/EnglishInflectorTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,15 @@ public static function pluralizeProvider()
178178
['access', 'accesses'],
179179
['address', 'addresses'],
180180
['agenda', 'agendas'],
181+
['aircraft', 'aircraft'],
181182
['alumnus', 'alumni'],
182183
['analysis', 'analyses'],
183184
['antenna', 'antennas'], // antennae
184185
['appendix', ['appendicies', 'appendixes']],
185186
['arch', 'arches'],
186187
['atlas', 'atlases'],
187188
['axe', 'axes'],
189+
['axis', 'axes'],
188190
['baby', 'babies'],
189191
['bacterium', 'bacteria'],
190192
['base', 'bases'],

0 commit comments

Comments
 (0)