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 b598243

Browse filesBrowse files
committed
Merge branch '5.4' into 6.0
* 5.4: [SecurityBundle] Fixed LogicException message of FirewallAwareTrait [LDAP] Fix resource type checks & docblocks on PHP 8.1 Revert "feature #43094 [Console] Add support of RGB functional notation (alexandre-daubois)" Fix Redis replication on Redis <5 Fix decorating non-entrypoint authenticators [Ldap] Make LdapAuthenticator an EntryPoint
2 parents 563acb8 + 6b1d9b8 commit b598243
Copy full SHA for b598243

File tree

11 files changed

+139
-80
lines changed
Filter options

11 files changed

+139
-80
lines changed

‎src/Symfony/Bundle/SecurityBundle/Security/FirewallAwareTrait.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Security/FirewallAwareTrait.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ private function getForFirewall(): object
2929
{
3030
$serviceIdentifier = str_replace('FirewallAware', '', static::class);
3131
if (null === $request = $this->requestStack->getCurrentRequest()) {
32-
throw new \LogicException('Cannot determine the correct '.$serviceIdentifier.' to use: there is no active Request and so, the firewall cannot be determined. Try using a specific '.$serviceIdentifier().' service.');
32+
throw new \LogicException('Cannot determine the correct '.$serviceIdentifier.' to use: there is no active Request and so, the firewall cannot be determined. Try using a specific '.$serviceIdentifier.' service.');
3333
}
3434

3535
$firewall = $this->firewallMap->getFirewallConfig($request);
+34Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace Symfony\Bundle\SecurityBundle\Tests\Security;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
7+
use Symfony\Bundle\SecurityBundle\Security\UserAuthenticator;
8+
use Symfony\Component\DependencyInjection\Container;
9+
use Symfony\Component\HttpFoundation\Request;
10+
use Symfony\Component\HttpFoundation\RequestStack;
11+
use Symfony\Component\Security\Core\User\InMemoryUser;
12+
use Symfony\Component\Security\Core\User\InMemoryUserProvider;
13+
use Symfony\Component\Security\Http\Authenticator\HttpBasicAuthenticator;
14+
15+
class UserAuthenticatorTest extends TestCase
16+
{
17+
public function testThrowsLogicExceptionIfCurrentRequestIsNull()
18+
{
19+
$container = new Container();
20+
$firewallMap = new FirewallMap($container, []);
21+
$requestStack = new RequestStack();
22+
$user = new InMemoryUser('username', 'password');
23+
$userProvider = new InMemoryUserProvider();
24+
$authenticator = new HttpBasicAuthenticator('name', $userProvider);
25+
$request = new Request();
26+
27+
$userAuthenticator = new UserAuthenticator($firewallMap, $container, $requestStack);
28+
29+
$this->expectException(\LogicException::class);
30+
$this->expectExceptionMessage('Cannot determine the correct Symfony\Bundle\SecurityBundle\Security\UserAuthenticator to use: there is no active Request and so, the firewall cannot be determined. Try using a specific Symfony\Bundle\SecurityBundle\Security\UserAuthenticator service.');
31+
32+
$userAuthenticator->authenticateUser($user, $authenticator, $request);
33+
}
34+
}

‎src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/Adapter/RedisTagAwareAdapter.php
+23-2Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Predis\Connection\Aggregate\PredisCluster;
1616
use Predis\Connection\Aggregate\ReplicationInterface;
1717
use Predis\Response\Status;
18+
use Symfony\Component\Cache\CacheItem;
1819
use Symfony\Component\Cache\Exception\InvalidArgumentException;
1920
use Symfony\Component\Cache\Exception\LogicException;
2021
use Symfony\Component\Cache\Marshaller\DeflateMarshaller;
@@ -158,6 +159,12 @@ protected function doDeleteYieldTags(array $ids): iterable
158159
});
159160

160161
foreach ($results as $id => $result) {
162+
if ($result instanceof \RedisException) {
163+
CacheItem::log($this->logger, 'Failed to delete key "{key}": '.$result->getMessage(), ['key' => substr($id, \strlen($this->namespace)), 'exception' => $result]);
164+
165+
continue;
166+
}
167+
161168
try {
162169
yield $id => !\is_string($result) || '' === $result ? [] : $this->marshaller->unmarshall($result);
163170
} catch (\Exception $e) {
@@ -196,6 +203,8 @@ protected function doInvalidate(array $tagIds): bool
196203
// gargage collect that set from the client side.
197204

198205
$lua = <<<'EOLUA'
206+
redis.replicate_commands()
207+
199208
local cursor = '0'
200209
local id = KEYS[1]
201210
repeat
@@ -233,14 +242,26 @@ protected function doInvalidate(array $tagIds): bool
233242
});
234243

235244
$lua = <<<'EOLUA'
245+
redis.replicate_commands()
246+
236247
local id = KEYS[1]
237248
local cursor = table.remove(ARGV)
238249
redis.call('SREM', '{'..id..'}'..id, unpack(ARGV))
239250
240251
return redis.call('SSCAN', '{'..id..'}'..id, cursor, 'COUNT', 5000)
241252
EOLUA;
242253

243-
foreach ($results as $id => [$cursor, $ids]) {
254+
$success = true;
255+
foreach ($results as $id => $values) {
256+
if ($values instanceof \RedisException) {
257+
CacheItem::log($this->logger, 'Failed to invalidate key "{key}": '.$values->getMessage(), ['key' => substr($id, \strlen($this->namespace)), 'exception' => $values]);
258+
$success = false;
259+
260+
continue;
261+
}
262+
263+
[$cursor, $ids] = $values;
264+
244265
while ($ids || '0' !== $cursor) {
245266
$this->doDelete($ids);
246267

@@ -263,7 +284,7 @@ protected function doInvalidate(array $tagIds): bool
263284
}
264285
}
265286

266-
return true;
287+
return $success;
267288
}
268289

269290
private function getRedisEvictionPolicy(): string

‎src/Symfony/Component/Console/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/CHANGELOG.md
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ CHANGELOG
1515

1616
* Add `TesterTrait::assertCommandIsSuccessful()` to test command
1717
* Deprecate `HelperSet::setCommand()` and `getCommand()` without replacement
18-
* Add `rgb(r, g, b)` notation support for output colors
1918

2019
5.3
2120
---

‎src/Symfony/Component/Console/Color.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Color.php
-25Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ final class Color
4949
'conceal' => ['set' => 8, 'unset' => 28],
5050
];
5151

52-
private const RGB_FUNCTIONAL_NOTATION_REGEX = '/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/';
53-
5452
private string $foreground;
5553
private string $background;
5654
private array $options = [];
@@ -118,10 +116,6 @@ private function parseColor(string $color, bool $background = false): string
118116
return '';
119117
}
120118

121-
if (str_starts_with($color, 'rgb(')) {
122-
$color = $this->rgbToHex($color);
123-
}
124-
125119
if ('#' === $color[0]) {
126120
$color = substr($color, 1);
127121

@@ -183,23 +177,4 @@ private function getSaturation(int $r, int $g, int $b): int
183177

184178
return (int) $diff * 100 / $v;
185179
}
186-
187-
private function rgbToHex(string $color): string
188-
{
189-
if (!preg_match(self::RGB_FUNCTIONAL_NOTATION_REGEX, $color, $matches)) {
190-
throw new InvalidArgumentException(sprintf('Invalid RGB functional notation; should be of the form "rgb(r, g, b)", got "%s".', $color));
191-
}
192-
193-
$rgb = \array_slice($matches, 1);
194-
195-
$hexString = array_map(function ($element) {
196-
if ($element > 255) {
197-
throw new InvalidArgumentException(sprintf('Invalid color component; value should be between 0 and 255, got %d.', $element));
198-
}
199-
200-
return str_pad(dechex((int) $element), 2, '0', \STR_PAD_LEFT);
201-
}, $rgb);
202-
203-
return '#'.implode('', $hexString);
204-
}
205180
}

‎src/Symfony/Component/Console/Tests/ColorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Tests/ColorTest.php
-32Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Console\Color;
16-
use Symfony\Component\Console\Exception\InvalidArgumentException;
1716

1817
class ColorTest extends TestCase
1918
{
@@ -43,9 +42,6 @@ public function testTrueColors()
4342

4443
$color = new Color('#ffffff', '#000000');
4544
$this->assertSame("\033[38;2;255;255;255;48;2;0;0;0m \033[39;49m", $color->apply(' '));
46-
47-
$color = new Color('rgb(255, 255, 255)', 'rgb(0, 0, 0)');
48-
$this->assertSame("\033[38;2;255;255;255;48;2;0;0;0m \033[39;49m", $color->apply(' '));
4945
}
5046

5147
public function testDegradedTrueColors()
@@ -63,32 +59,4 @@ public function testDegradedTrueColors()
6359
putenv('COLORTERM='.$colorterm);
6460
}
6561
}
66-
67-
/**
68-
* @dataProvider provideMalformedRgbStrings
69-
*/
70-
public function testMalformedRgbString(string $color, string $exceptionMessage)
71-
{
72-
$this->expectException(InvalidArgumentException::class);
73-
$this->expectExceptionMessage($exceptionMessage);
74-
75-
new Color($color);
76-
}
77-
78-
public function provideMalformedRgbStrings(): \Generator
79-
{
80-
yield ['rgb()', 'Invalid RGB functional notation; should be of the form "rgb(r, g, b)", got "rgb()".'];
81-
82-
yield ['rgb(0, 0)', 'Invalid RGB functional notation; should be of the form "rgb(r, g, b)", got "rgb(0, 0)".'];
83-
84-
yield ['rgb(0, 0, 0, 0)', 'Invalid RGB functional notation; should be of the form "rgb(r, g, b)", got "rgb(0, 0, 0, 0)".'];
85-
86-
yield ['rgb(-1, 0, 0)', 'Invalid RGB functional notation; should be of the form "rgb(r, g, b)", got "rgb(-1, 0, 0)".'];
87-
88-
yield ['rgb(invalid, 0, 0)', 'Invalid RGB functional notation; should be of the form "rgb(r, g, b)", got "rgb(invalid, 0, 0)".'];
89-
90-
yield ['rgb(256, 0, 0)', 'Invalid color component; value should be between 0 and 255, got 256.'];
91-
92-
yield ['rgb(0, 0, 0', 'Invalid RGB functional notation; should be of the form "rgb(r, g, b)", got "rgb(0, 0, 0".'];
93-
}
9462
}

‎src/Symfony/Component/Ldap/Adapter/ExtLdap/Connection.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Ldap/Adapter/ExtLdap/Connection.php
+4-5Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Ldap\Adapter\ExtLdap;
1313

14+
use LDAP\Connection as LDAPConnection;
1415
use Symfony\Component\Ldap\Adapter\AbstractConnection;
1516
use Symfony\Component\Ldap\Exception\AlreadyExistsException;
1617
use Symfony\Component\Ldap\Exception\ConnectionException;
@@ -31,7 +32,7 @@ class Connection extends AbstractConnection
3132

3233
private bool $bound = false;
3334

34-
/** @var resource */
35+
/** @var resource|LDAPConnection */
3536
private $connection;
3637

3738
public function __sleep(): array
@@ -85,9 +86,7 @@ public function bind(string $dn = null, string $password = null)
8586
}
8687

8788
/**
88-
* Returns a link resource.
89-
*
90-
* @return resource
89+
* @return resource|LDAPConnection
9190
*
9291
* @internal
9392
*/
@@ -161,7 +160,7 @@ private function connect()
161160

162161
private function disconnect()
163162
{
164-
if ($this->connection && \is_resource($this->connection)) {
163+
if ($this->connection) {
165164
ldap_unbind($this->connection);
166165
}
167166

‎src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php
+17-7Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\Ldap\Adapter\ExtLdap;
1313

14+
use LDAP\Connection as LDAPConnection;
15+
use LDAP\Result;
1416
use Symfony\Component\Ldap\Adapter\AbstractQuery;
1517
use Symfony\Component\Ldap\Adapter\CollectionInterface;
1618
use Symfony\Component\Ldap\Exception\LdapException;
@@ -25,7 +27,10 @@ class Query extends AbstractQuery
2527
// As of PHP 7.2, we can use LDAP_CONTROL_PAGEDRESULTS instead of this
2628
public const PAGINATION_OID = '1.2.840.113556.1.4.319';
2729

28-
/** @var resource[] */
30+
/** @var Connection */
31+
protected $connection;
32+
33+
/** @var resource[]|Result[] */
2934
private array $results;
3035

3136
private array $serverctrls = [];
@@ -145,7 +150,7 @@ public function execute(): CollectionInterface
145150
* Returns an LDAP search resource. If this query resulted in multiple searches, only the first
146151
* page will be returned.
147152
*
148-
* @return resource|null
153+
* @return resource|Result|null
149154
*
150155
* @internal
151156
*/
@@ -157,7 +162,7 @@ public function getResource(int $idx = 0)
157162
/**
158163
* Returns all LDAP search resources.
159164
*
160-
* @return resource[]
165+
* @return resource[]|Result[]
161166
*
162167
* @internal
163168
*/
@@ -199,6 +204,11 @@ private function resetPagination()
199204

200205
/**
201206
* Sets LDAP pagination controls.
207+
<<<<<<< HEAD
208+
=======
209+
*
210+
* @param resource|LDAPConnection $con
211+
>>>>>>> 5.4
202212
*/
203213
private function controlPagedResult(int $pageSize, bool $critical, string $cookie): bool
204214
{
@@ -219,8 +229,8 @@ private function controlPagedResult(int $pageSize, bool $critical, string $cooki
219229
/**
220230
* Retrieve LDAP pagination cookie.
221231
*
222-
* @param resource $con
223-
* @param resource $result
232+
* @param resource|LDAPConnection $con
233+
* @param resource|Result $result
224234
*/
225235
private function controlPagedResultResponse($con, $result): string
226236
{
@@ -232,9 +242,9 @@ private function controlPagedResultResponse($con, $result): string
232242
/**
233243
* Calls actual LDAP search function with the prepared options and parameters.
234244
*
235-
* @param resource $con
245+
* @param resource|LDAPConnection $con
236246
*
237-
* @return resource|false
247+
* @return resource|Result|false
238248
*/
239249
private function callSearchFunction($con, callable $func, int $sizeLimit)
240250
{

‎src/Symfony/Component/Ldap/Security/LdapAuthenticator.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Ldap/Security/LdapAuthenticator.php
+22-1Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
use Symfony\Component\Security\Core\Exception\AuthenticationException;
1818
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
1919
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
20+
use Symfony\Component\Security\Http\Authenticator\InteractiveAuthenticatorInterface;
21+
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
22+
use Symfony\Component\Security\Http\EntryPoint\Exception\NotAnEntryPointException;
2023

2124
/**
2225
* This class decorates internal authenticators to add the LDAP integration.
@@ -29,7 +32,7 @@
2932
*
3033
* @final
3134
*/
32-
class LdapAuthenticator implements AuthenticatorInterface
35+
class LdapAuthenticator implements AuthenticationEntryPointInterface, InteractiveAuthenticatorInterface
3336
{
3437
private AuthenticatorInterface $authenticator;
3538
private string $ldapServiceId;
@@ -75,4 +78,22 @@ public function onAuthenticationFailure(Request $request, AuthenticationExceptio
7578
{
7679
return $this->authenticator->onAuthenticationFailure($request, $exception);
7780
}
81+
82+
public function start(Request $request, AuthenticationException $authException = null): Response
83+
{
84+
if (!$this->authenticator instanceof AuthenticationEntryPointInterface) {
85+
throw new NotAnEntryPointException(sprintf('Decorated authenticator "%s" does not implement interface "%s".', get_debug_type($this->authenticator), AuthenticationEntryPointInterface::class));
86+
}
87+
88+
return $this->authenticator->start($request, $authException);
89+
}
90+
91+
public function isInteractive(): bool
92+
{
93+
if ($this->authenticator instanceof InteractiveAuthenticatorInterface) {
94+
return $this->authenticator->isInteractive();
95+
}
96+
97+
return false;
98+
}
7899
}
+22Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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\EntryPoint\Exception;
13+
14+
/**
15+
* Thrown by generic decorators when a decorated authenticator does not implement
16+
* {@see AuthenticationEntryPointInterface}.
17+
*
18+
* @author Robin Chalas <robin.chalas@gmail.com>
19+
*/
20+
class NotAnEntryPointException extends \RuntimeException
21+
{
22+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.