Skip to content

Commit

Permalink
Added option to set redis user name in redis options
Browse files Browse the repository at this point in the history
  • Loading branch information
cbraunVBM committed Apr 30, 2024
1 parent 82c636c commit 6e2bf1a
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 3 deletions.
23 changes: 22 additions & 1 deletion src/RedisOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace Laminas\Cache\Storage\Adapter;

use Laminas\Cache\Exception;
use Laminas\Cache\Storage\Adapter\RedisResourceManager;

use function sprintf;
use function strlen;
Expand Down Expand Up @@ -261,4 +260,26 @@ public function getPassword()
{
return $this->getResourceManager()->getPassword($this->getResourceId());
}

/**
* Set resource user
*
* @param string $user ACL User
* @return RedisOptions Provides a fluent interface
*/
public function setUser($user)
{
$this->getResourceManager()->setUser($this->getResourceId(), $user);
return $this;
}

/**
* Get resource user
*
* @return string
*/
public function getUser()
{
return $this->getResourceManager()->getUser($this->getResourceId());
}
}
80 changes: 78 additions & 2 deletions src/RedisResourceManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,22 @@ public function getPassword($id)
return $resource['password'];
}

/**
* Get redis resource user
*
* @param string $id
* @return string
*/
public function getUser($id)
{
if (! $this->hasResource($id)) {
throw new Exception\RuntimeException("No resource with id '{$id}'");
}

$resource = &$this->resources[$id];
return $resource['user'];

Check failure on line 139 in src/RedisResourceManager.php

View workflow job for this annotation

GitHub Actions / QA Checks (Psalm [8.1, locked], ubuntu-latest, laminas/laminas-continuous-integration-action@v1, ...

MixedArrayAccess

src/RedisResourceManager.php:139:16: MixedArrayAccess: Cannot access array value on mixed variable $resource (see https://psalm.dev/051)

Check failure on line 139 in src/RedisResourceManager.php

View workflow job for this annotation

GitHub Actions / QA Checks (Psalm [8.1, locked], ubuntu-latest, laminas/laminas-continuous-integration-action@v1, ...

MixedReturnStatement

src/RedisResourceManager.php:139:16: MixedReturnStatement: Could not infer a return type (see https://psalm.dev/138)
}

/**
* Gets a redis resource
*
Expand Down Expand Up @@ -279,6 +295,36 @@ protected function extractPassword($resource, $serverUri)
return $server['pass'] ?? null;
}

/**
* Extract password to be used on connection
*
* @param mixed $resource
* @param mixed $serverUri
* @return string|null

Check failure on line 303 in src/RedisResourceManager.php

View workflow job for this annotation

GitHub Actions / QA Checks (Psalm [8.1, locked], ubuntu-latest, laminas/laminas-continuous-integration-action@v1, ...

MixedInferredReturnType

src/RedisResourceManager.php:303:16: MixedInferredReturnType: Could not verify return type 'null|string' for Laminas\Cache\Storage\Adapter\RedisResourceManager::extractUser (see https://psalm.dev/047)
*/
protected function extractUser($resource, $serverUri)
{
if (! empty($resource['user'])) {
return $resource['user'];

Check failure on line 308 in src/RedisResourceManager.php

View workflow job for this annotation

GitHub Actions / QA Checks (Psalm [8.1, locked], ubuntu-latest, laminas/laminas-continuous-integration-action@v1, ...

MixedArrayAccess

src/RedisResourceManager.php:308:20: MixedArrayAccess: Cannot access array value on mixed variable $resource (see https://psalm.dev/051)

Check failure on line 308 in src/RedisResourceManager.php

View workflow job for this annotation

GitHub Actions / QA Checks (Psalm [8.1, locked], ubuntu-latest, laminas/laminas-continuous-integration-action@v1, ...

MixedReturnStatement

src/RedisResourceManager.php:308:20: MixedReturnStatement: Could not infer a return type (see https://psalm.dev/138)
}

if (! is_string($serverUri)) {
return null;
}

// parse server from URI host{:?port}
$server = trim($serverUri);

if (strpos($server, '/') === 0) {
return null;
}

//non unix domain socket connection
$server = parse_url($server);

return $server['user'] ?? null;
}

/**
* Connects to redis server
*
Expand Down Expand Up @@ -315,7 +361,9 @@ protected function connect(array &$resource)
}

$resource['initialized'] = true;
if ($resource['password']) {
if ($resource['user'] && $resource['password']) {
$redis->auth([$resource['user'], $resource['password']]);
} elseif ($resource['password']) {
$redis->auth($resource['password']);
}
$redis->select($resource['database']);
Expand All @@ -339,6 +387,7 @@ public function setResource($id, $resource)
'persistent_id' => '',
'lib_options' => [],
'server' => [],
'user' => '',
'password' => '',
'database' => 0,
'resource' => null,
Expand All @@ -361,6 +410,7 @@ public function setResource($id, $resource)
// #6495 note: order is important here, as `normalizeServer` applies destructive
// transformations on $resource['server']
$resource['password'] = $this->extractPassword($resource, $resource['server']);
$resource['user'] = $this->extractUser($resource, $resource['server']);

$this->normalizeServer($resource['server']);
} else {
Expand Down Expand Up @@ -624,12 +674,17 @@ public function setServer($id, $server)
$resource = &$this->resources[$id];
$resource['password'] = $this->extractPassword($resource, $server);

$resource['user'] = $this->extractUser($resource, $server);

Check failure on line 677 in src/RedisResourceManager.php

View workflow job for this annotation

GitHub Actions / QA Checks (Psalm [8.1, locked], ubuntu-latest, laminas/laminas-continuous-integration-action@v1, ...

MixedArrayAssignment

src/RedisResourceManager.php:677:9: MixedArrayAssignment: Cannot access array value on mixed variable $resource['user'] (see https://psalm.dev/117)

if ($resource['resource'] instanceof RedisResource) {
$resourceParams = ['server' => $server];

if (! empty($resource['password'])) {
$resourceParams['password'] = $resource['password'];
}
if (! empty($resource['user'])) {
$resourceParams['user'] = $resource['user'];
}

$this->setResource($id, $resourceParams);
} else {
Expand All @@ -644,7 +699,7 @@ public function setServer($id, $server)
*
* @param string $id
* @param string $password
* @return RedisResource
* @return RedisResourceManager
*/
public function setPassword($id, $password)
{
Expand Down Expand Up @@ -713,4 +768,25 @@ private function getRedisInfo(RedisResource $redis): array

return $info;
}

/**
* Set redis user
*
* @param string $id
* @param string $user
* @return RedisResourceManager
*/
public function setUser($id, $user)
{
if (! $this->hasResource($id)) {
return $this->setResource($id, [
'user' => $user,
]);
}

$resource = &$this->resources[$id];

Check failure on line 787 in src/RedisResourceManager.php

View workflow job for this annotation

GitHub Actions / QA Checks (Psalm [8.1, locked], ubuntu-latest, laminas/laminas-continuous-integration-action@v1, ...

UnsupportedPropertyReferenceUsage

src/RedisResourceManager.php:787:9: UnsupportedPropertyReferenceUsage: This reference cannot be analyzed by Psalm. (see https://psalm.dev/321)
$resource['user'] = $user;

Check failure on line 788 in src/RedisResourceManager.php

View workflow job for this annotation

GitHub Actions / QA Checks (Psalm [8.1, locked], ubuntu-latest, laminas/laminas-continuous-integration-action@v1, ...

MixedArrayAssignment

src/RedisResourceManager.php:788:9: MixedArrayAssignment: Cannot access array value on mixed variable $resource['user'] (see https://psalm.dev/117)
$resource['initialized'] = false;
return $this;
}
}
11 changes: 11 additions & 0 deletions test/integration/Laminas/RedisTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,17 @@ public function testOptionsGetSetPassword(): void
'Password was set incorrectly using RedisOptions'
);
}

Check failure on line 331 in test/integration/Laminas/RedisTest.php

View workflow job for this annotation

GitHub Actions / QA Checks (PHPCodeSniffer [8.1, locked], ubuntu-latest, laminas/laminas-continuous-integration-ac...

Whitespace found at end of line
public function testOptionsGetSetUser(): void
{
$user = 'dummyuser';
$this->options->setUser($user);
$this->assertEquals(
$user,
$this->options->getUser(),
'User was set incorrectly using RedisOptions'
);
}

public function testTouchItem(): void
{
Expand Down
52 changes: 52 additions & 0 deletions test/unit/RedisResourceManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public function testSetServerWithPasswordInUri(): void
$this->assertEquals('testhost', $server['host']);
$this->assertEquals(1234, $server['port']);
$this->assertEquals('dummypass', $this->resourceManager->getPassword($dummyResId));
$this->assertEquals('dummyuser', $this->resourceManager->getUser($dummyResId));
}

/**
Expand All @@ -71,6 +72,27 @@ public function testSetServerWithPasswordInParameters(): void
$this->assertEquals('testhost', $server['host']);
$this->assertEquals(1234, $server['port']);
$this->assertEquals('abcd1234', $this->resourceManager->getPassword($dummyResId2));
$this->assertEquals('dummyuser', $this->resourceManager->getUser($dummyResId2));
}

public function testSetServerWithPasswordInParametersAndNoUser(): void
{
$server = 'redis://testhost:1234';
$dummyResId2 = '12345678901';
$resource = [
'persistent_id' => 'my_connection_name',
'server' => $server,
'password' => 'abcd1234',
];

$this->resourceManager->setResource($dummyResId2, $resource);

$server = $this->resourceManager->getServer($dummyResId2);

$this->assertEquals('testhost', $server['host']);
$this->assertEquals(1234, $server['port']);
$this->assertEquals('abcd1234', $this->resourceManager->getPassword($dummyResId2));
$this->assertEquals('', $this->resourceManager->getUser($dummyResId2));
}

/**
Expand Down Expand Up @@ -287,6 +309,36 @@ public function testWillCatchAuthDuringConnectException(): void
$this->resourceManager->getResource('default');
}

public function testWillCatchAuthDuringConnectExceptionWithUser(): void
{
$redis = $this->createMock(Redis::class);

$redis
->method('connect')
->willReturn(true);

$redis
->expects(self::atLeastOnce())
->method('auth')
->with(['dummyuser', 'secret'])
->willThrowException(new RedisException('test'));

$this->resourceManager->setResource(
'default',
[
'resource' => $redis,
'initialized' => false,
'server' => 'somewhere:6379',
'password' => 'secret',
'user' => 'dummyuser',
]
);

$this->expectException(RedisRuntimeException::class);
$this->expectExceptionMessage('test');
$this->resourceManager->getResource('default');
}

public function testWillCatchSelectDatabaseException(): void
{
$redis = $this->createMock(Redis::class);
Expand Down

0 comments on commit 6e2bf1a

Please sign in to comment.