Skip to content

Commit eb5e703

Browse files
author
alessandro
committed
Support authentication
1 parent 3cf33b0 commit eb5e703

File tree

5 files changed

+93
-15
lines changed

5 files changed

+93
-15
lines changed

src/Client/RedisClient.php

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace Palicao\PhpRedisTimeSeries\Client;
55

6+
use Palicao\PhpRedisTimeSeries\Exception\RedisAuthenticationException;
67
use Palicao\PhpRedisTimeSeries\Exception\RedisClientException;
78
use Redis;
89
use RedisException;
@@ -62,10 +63,12 @@ private function connectIfNeeded(): void
6263
$this->redis->getLastError() ?? 'unknown error'
6364
));
6465
}
66+
67+
$this->authenticate($params->getUsername(), $params->getPassword());
6568
}
6669

6770
/**
68-
* @param array $params
71+
* @param string[] $params
6972
* @return mixed
7073
* @throws RedisException
7174
* @throws RedisClientException
@@ -78,4 +81,37 @@ public function executeCommand(array $params)
7881
$this->redis->setOption(8, $value);
7982
return $this->redis->rawCommand(...$params);
8083
}
84+
85+
/**
86+
* @param string|null $username
87+
* @param string|null $password
88+
* @throws RedisAuthenticationException
89+
*/
90+
private function authenticate(?string $username, ?string $password): void
91+
{
92+
try {
93+
if ($password) {
94+
if ($username) {
95+
// Calling auth() with an array throws a TypeError in some cases
96+
/**
97+
* @noinspection PhpMethodParametersCountMismatchInspection
98+
* @var bool $result
99+
*/
100+
$result = $this->redis->rawCommand('AUTH', $username, $password);
101+
} else {
102+
/** @psalm-suppress PossiblyNullArgument */
103+
$result = $this->redis->auth($password);
104+
}
105+
if ($result === false) {
106+
throw new RedisAuthenticationException(sprintf(
107+
'Failure authenticating user %s', $username ?: 'default'
108+
));
109+
}
110+
}
111+
} /** @noinspection PhpRedundantCatchClauseInspection */ catch (RedisException $e) {
112+
throw new RedisAuthenticationException(sprintf(
113+
'Failure authenticating user %s: %s', $username ?: 'default', $e->getMessage()
114+
));
115+
}
116+
}
81117
}

src/Client/RedisClientInterface.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33

44
namespace Palicao\PhpRedisTimeSeries\Client;
55

6+
use RedisException;
7+
68
interface RedisClientInterface
79
{
810
/**
9-
* @param array $params
11+
* @param string[] $params
1012
* @return mixed
13+
* @throws RedisException
1114
*/
1215
public function executeCommand(array $params);
1316
}

src/Client/RedisConnectionParams.php

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace Palicao\PhpRedisTimeSeries\Client;
55

6-
class RedisConnectionParams
6+
final class RedisConnectionParams
77
{
88
/** @var bool */
99
private $persistentConnection;
@@ -23,11 +23,30 @@ class RedisConnectionParams
2323
/** @var float */
2424
private $readTimeout;
2525

26-
public function __construct(string $host = '127.0.0.1', int $port = 6379)
27-
{
26+
/** @var string|null */
27+
private $username;
28+
29+
/** @var string|null */
30+
private $password;
31+
32+
/**
33+
* RedisConnectionParams constructor.
34+
* @param string $host
35+
* @param int $port
36+
* @param string|null $username
37+
* @param string|null $password
38+
*/
39+
public function __construct(
40+
string $host = '127.0.0.1',
41+
int $port = 6379,
42+
?string $username = null,
43+
?string $password = null
44+
) {
2845
$this->persistentConnection = false;
2946
$this->host = $host;
3047
$this->port = $port;
48+
$this->username = $username;
49+
$this->password = $password;
3150
$this->timeout = 0;
3251
$this->retryInterval = 0;
3352
$this->readTimeout = 0.0;
@@ -106,4 +125,14 @@ public function getReadTimeout(): float
106125
{
107126
return $this->readTimeout;
108127
}
128+
129+
public function getUsername(): ?string
130+
{
131+
return $this->username;
132+
}
133+
134+
public function getPassword(): ?string
135+
{
136+
return $this->password;
137+
}
109138
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Palicao\PhpRedisTimeSeries\Exception;
5+
6+
use RuntimeException;
7+
8+
final class RedisAuthenticationException extends RuntimeException
9+
{
10+
}

tests/Unit/RedisClientTest.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,16 @@ class RedisClientTest extends TestCase
1616
public function testExecuteCommand(): void
1717
{
1818
$redisMock = $this->createMock(Redis::class);
19-
$redisMock->expects($this->once())->method('isConnected')->willReturn(false);
20-
$redisMock->expects($this->once())->method('connect')->with(
19+
$redisMock->expects(self::once())->method('isConnected')->willReturn(false);
20+
$redisMock->expects(self::once())->method('connect')->with(
2121
'127.0.0.1',
2222
6379,
2323
3,
2424
null,
2525
1,
2626
2.2
2727
);
28-
$redisMock->expects($this->once())->method('rawCommand')->with('MY', 'command');
28+
$redisMock->expects(self::once())->method('rawCommand')->with('MY', 'command');
2929
$connectionParams = new RedisConnectionParams();
3030
$connectionParams->setRetryInterval(1)
3131
->setReadTimeout(2.2)
@@ -37,12 +37,12 @@ public function testExecuteCommand(): void
3737
public function testPersistentConnection(): void
3838
{
3939
$redisMock = $this->createMock(Redis::class);
40-
$redisMock->expects($this->once())->method('isConnected')->willReturn(false);
41-
$redisMock->expects($this->once())->method('pconnect')->with(
40+
$redisMock->expects(self::once())->method('isConnected')->willReturn(false);
41+
$redisMock->expects(self::once())->method('pconnect')->with(
4242
'127.0.0.1',
4343
6379,
4444
0,
45-
$this->isType(IsType::TYPE_STRING),
45+
self::isType(IsType::TYPE_STRING),
4646
0,
4747
0.0
4848
);
@@ -55,9 +55,9 @@ public function testPersistentConnection(): void
5555
public function testDontConnectIfNotNecessary(): void
5656
{
5757
$redisMock = $this->createMock(Redis::class);
58-
$redisMock->expects($this->once())->method('isConnected')->willReturn(true);
59-
$redisMock->expects($this->never())->method('connect');
60-
$redisMock->expects($this->never())->method('pconnect');
58+
$redisMock->expects(self::once())->method('isConnected')->willReturn(true);
59+
$redisMock->expects(self::never())->method('connect');
60+
$redisMock->expects(self::never())->method('pconnect');
6161
$connectionParams = new RedisConnectionParams();
6262
$sut = new RedisClient($redisMock, $connectionParams);
6363
$sut->executeCommand(['MY', 'command']);
@@ -67,7 +67,7 @@ public function testFailureToConnectThrowsException(): void
6767
{
6868
$this->expectException(RedisClientException::class);
6969
$redisMock = $this->createMock(Redis::class);
70-
$redisMock->expects($this->once())->method('connect')->willReturn(false);
70+
$redisMock->expects(self::once())->method('connect')->willReturn(false);
7171
$connectionParams = new RedisConnectionParams();
7272
$sut = new RedisClient($redisMock, $connectionParams);
7373
$sut->executeCommand(['MY', 'command']);

0 commit comments

Comments
 (0)