bug #37791 Fix redis connect with empty password (alexander-schranz)

This PR was squashed before being merged into the 4.4 branch.

Discussion
----------

Fix redis connect with empty password

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix -
| License       | MIT
| Doc PR        | symfony/symfony-docs#...

If you use DSN like this it will fail as auth is called with an empty password:

```env
redis://%env(resolve:REDIS_PASSWORD)%@%env(resolve:REDIS_HOST)%
```

The auth should only be called when a password is set to a specific string.

Else it will fail with:

> ERR Client sent AUTH, but no password is set

Redis Conf "redis-nopass.conf":

```ini
requirepass ""
```

Commits
-------

9946f7fecf Fix redis connect with empty password
This commit is contained in:
Fabien Potencier 2020-08-10 15:30:12 +02:00
commit b2e99e2a76
3 changed files with 32 additions and 1 deletions

View File

@ -103,6 +103,10 @@ trait RedisTrait
$params = preg_replace_callback('#^'.$scheme.':(//)?(?:(?:[^:@]*+:)?([^@]*+)@)?#', function ($m) use (&$auth) {
if (isset($m[2])) {
$auth = $m[2];
if ('' === $auth) {
$auth = null;
}
}
return 'file:'.($m[1] ?? '');

View File

@ -110,6 +110,28 @@ class ConnectionTest extends TestCase
Connection::fromDsn('redis://password@localhost/queue', [], $redis);
}
public function testNoAuthWithEmptyPassword()
{
$redis = $this->getMockBuilder(\Redis::class)->disableOriginalConstructor()->getMock();
$redis->expects($this->exactly(0))->method('auth')
->with('')
->willThrowException(new \RuntimeException());
Connection::fromDsn('redis://@localhost/queue', [], $redis);
}
public function testAuthZeroPassword()
{
$redis = $this->getMockBuilder(\Redis::class)->disableOriginalConstructor()->getMock();
$redis->expects($this->exactly(1))->method('auth')
->with('0')
->willReturn(true);
Connection::fromDsn('redis://0@localhost/queue', [], $redis);
}
public function testFailedAuth()
{
$this->expectException(\InvalidArgumentException::class);

View File

@ -55,7 +55,12 @@ class Connection
$this->connection->connect($connectionCredentials['host'] ?? '127.0.0.1', $connectionCredentials['port'] ?? 6379);
$this->connection->setOption(\Redis::OPT_SERIALIZER, $redisOptions['serializer'] ?? \Redis::SERIALIZER_PHP);
if (isset($connectionCredentials['auth']) && !$this->connection->auth($connectionCredentials['auth'])) {
$auth = $connectionCredentials['auth'] ?? null;
if ('' === $auth) {
$auth = null;
}
if (null !== $auth && !$this->connection->auth($auth)) {
throw new InvalidArgumentException('Redis connection failed: '.$redis->getLastError());
}