Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6d95721

Browse files
bug #62852 [Cache] Fix DSN auth not passed to clusters in RedisTrait (wikando-ck)
This PR was squashed before being merged into the 6.4 branch. Discussion ---------- [Cache] Fix DSN auth not passed to clusters in RedisTrait | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | #62765 | License | MIT This fix enables `symfony/cache` Redis-type cluster connections to use authentication from DSN. The cluster connections use `$params['auth']` instead of `$auth` in `RedisTrait::createConnection()`. The values that are extracted from the DSN in `$auth` are never merged into the `$params`. As this is a trait that is used in a connection factory, it's impossible to unit-test this. It can be reproduced with a redis-cluster that has no default-user or that has a password protected default user and then connecting to it using a DSN like `rediss://user:pass@redis-cluster:6379`. I've just tested it on an aws memoryDb cluster. Here's my research thread using deepwiki: https://deepwiki.com/search/in-redistraitphp-why-is-params_8008d228-37f0-42cb-8e6c-74a2c419d33a?mode=fast (note how it fails telling me which branch to target 🔢) Commits ------- 2149f6a [Cache] Fix DSN auth not passed to clusters in RedisTrait
2 parents 101a5cc + 2149f6a commit 6d95721

1 file changed

Lines changed: 13 additions & 12 deletions

File tree

src/Symfony/Component/Cache/Traits/RedisTrait.php

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ trait RedisTrait
3737
{
3838
private static array $defaultConnectionOptions = [
3939
'class' => null,
40+
'auth' => null,
4041
'persistent' => 0,
4142
'persistent_id' => null,
4243
'timeout' => 30,
@@ -99,6 +100,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra
99100
throw new CacheException('Cannot find the "redis" extension nor the "relay" extension nor the "predis/predis" package.');
100101
}
101102

103+
$auth = null;
102104
$params = preg_replace_callback('#^'.$scheme.':(//)?(?:(?:(?<user>[^:@]*+):)?(?<password>[^@]*+)@)?#', function ($m) use (&$auth) {
103105
if (isset($m['password'])) {
104106
if (\in_array($m['user'], ['', 'default'], true)) {
@@ -173,6 +175,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra
173175
}
174176

175177
$params += $query + $options + self::$defaultConnectionOptions;
178+
$params['auth'] ??= $auth;
176179

177180
if (isset($params['redis_sentinel']) && !class_exists(\Predis\Client::class) && !class_exists(\RedisSentinel::class) && !class_exists(Sentinel::class)) {
178181
throw new CacheException('Redis Sentinel support requires one of: "predis/predis", "ext-redis >= 5.2", "ext-relay".');
@@ -217,7 +220,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra
217220
do {
218221
$host = $hosts[$hostIndex]['host'] ?? $hosts[$hostIndex]['path'];
219222
$port = $hosts[$hostIndex]['port'] ?? 0;
220-
$passAuth = isset($params['auth']) && (!$isRedisExt || \defined('Redis::OPT_NULL_MULTIBULK_AS_NULL'));
223+
$passAuth = null !== $params['auth'] && (!$isRedisExt || \defined('Redis::OPT_NULL_MULTIBULK_AS_NULL'));
221224
$address = false;
222225

223226
if (isset($hosts[$hostIndex]['host']) && $tls) {
@@ -229,7 +232,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra
229232
}
230233

231234
try {
232-
if (version_compare(phpversion('redis'), '6.0.0', '>=') && $isRedisExt) {
235+
if ($isRedisExt && version_compare(phpversion('redis'), '6.0.0', '>=')) {
233236
$options = [
234237
'host' => $host,
235238
'port' => $port,
@@ -281,7 +284,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra
281284
}
282285
}
283286

284-
if (isset($params['auth'])) {
287+
if (null !== $params['auth']) {
285288
$extra['auth'] = $params['auth'];
286289
}
287290
@$redis->{$connect}($host, $port, (float) $params['timeout'], (string) $params['persistent_id'], $params['retry_interval'], $params['read_timeout'], ...\defined('Redis::SCAN_PREFIX') || !$isRedisExt ? [$extra] : []);
@@ -297,7 +300,7 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra
297300
throw new InvalidArgumentException('Redis connection failed: '.$error.'.');
298301
}
299302

300-
if ((null !== $auth && !$redis->auth($auth))
303+
if ((null !== $auth && $isRedisExt && version_compare(phpversion('redis'), '5.3', '<') && !$redis->auth($auth))
301304
// Due to a bug in phpredis we must always select the dbindex if persistent pooling is enabled
302305
// @see https://github.com/phpredis/phpredis/issues/1920
303306
// @see https://github.com/symfony/symfony/issues/51578
@@ -389,14 +392,12 @@ public static function createConnection(#[\SensitiveParameter] string $dsn, arra
389392
if ($params['dbindex']) {
390393
$params['parameters']['database'] = $params['dbindex'];
391394
}
392-
if (null !== $auth) {
393-
if (\is_array($auth)) {
394-
// ACL
395-
$params['parameters']['username'] = $auth[0];
396-
$params['parameters']['password'] = $auth[1];
397-
} else {
398-
$params['parameters']['password'] = $auth;
399-
}
395+
if (\is_array($params['auth'])) {
396+
// ACL
397+
$params['parameters']['username'] = $params['auth'][0];
398+
$params['parameters']['password'] = $params['auth'][1];
399+
} elseif (null !== $params['auth']) {
400+
$params['parameters']['password'] = $params['auth'];
400401
}
401402

402403
if (isset($params['ssl'])) {

0 commit comments

Comments
 (0)