Skip to content

Commit

Permalink
Create RedisDecodeCredentialsConfigOption
Browse files Browse the repository at this point in the history
  • Loading branch information
acelaya committed Nov 23, 2023
1 parent c505a19 commit dc6965c
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
* Add `CacheNamespaceConfigOption` to customize the cache namespace.
* Add support for PHP 8.3
* [#200](https://github.com/shlinkio/shlink-installer/issues/200) Add Matomo integration config options.
* Add `RedisDecodeCredentialsConfigOption` to enable/disable URL-decoding on redis server credentials.

### Changed
* *Nothing*
Expand Down
2 changes: 2 additions & 0 deletions config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
],
'INTEGRATIONS' => [
'Redis > servers' => Config\Option\Redis\RedisServersConfigOption::class,
'Redis > decode credentials' => Config\Option\Redis\RedisDecodeCredentialsConfigOption::class,
'Redis > sentinels service' => Config\Option\Redis\RedisSentinelServiceConfigOption::class,
'Redis > Pub/sub enabled' => Config\Option\Redis\RedisPubSubConfigOption::class,
Config\Option\Mercure\EnableMercureConfigOption::class,
Expand Down Expand Up @@ -140,6 +141,7 @@
Config\Option\UrlShortener\EnableTrailingSlashConfigOption::class => InvokableFactory::class,
Config\Option\UrlShortener\ShortUrlModeConfigOption::class => InvokableFactory::class,
Config\Option\Redis\RedisServersConfigOption::class => InvokableFactory::class,
Config\Option\Redis\RedisDecodeCredentialsConfigOption::class => InvokableFactory::class,
Config\Option\Redis\RedisSentinelServiceConfigOption::class => InvokableFactory::class,
Config\Option\Redis\RedisPubSubConfigOption::class => InvokableFactory::class,
Config\Option\Visit\VisitsWebhooksConfigOption::class => ConfigAbstractFactory::class,
Expand Down
38 changes: 38 additions & 0 deletions src/Config/Option/Redis/RedisDecodeCredentialsConfigOption.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace Shlinkio\Shlink\Installer\Config\Option\Redis;

use Shlinkio\Shlink\Installer\Config\Option\BaseConfigOption;
use Shlinkio\Shlink\Installer\Config\Option\DependentConfigOptionInterface;
use Symfony\Component\Console\Style\StyleInterface;

/** @deprecated */
class RedisDecodeCredentialsConfigOption extends BaseConfigOption implements DependentConfigOptionInterface
{
public function getEnvVar(): string
{
return 'REDIS_DECODE_CREDENTIALS';
}

public function shouldBeAsked(array $currentOptions): bool
{
$isRedisEnabled = $currentOptions[RedisServersConfigOption::ENV_VAR] ?? null;
return $isRedisEnabled !== null && parent::shouldBeAsked($currentOptions);
}

public function ask(StyleInterface $io, array $currentOptions): bool
{
return $io->confirm(
'Do you want redis credentials to be URL-decoded? '
. '(If you provided servers with URL-encoded credentials, this should be "yes")',
false,
);
}

public function getDependentOption(): string
{
return RedisServersConfigOption::class;
}
}
5 changes: 4 additions & 1 deletion src/Config/Option/Redis/RedisServersConfigOption.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ public function ask(StyleInterface $io, array $currentOptions): ?string
return null;
}

return $io->ask('Provide a comma-separated list of URIs (redis servers/sentinel instances)');
return $io->ask(
'Provide a comma-separated list of URIs (redis servers/sentinel instances). If they contains credentials '
. 'with URL-reserved chars, make sure they are URL-encoded',
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace ShlinkioTest\Shlink\Installer\Config\Option\Redis;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
use Shlinkio\Shlink\Installer\Config\Option\Redis\RedisDecodeCredentialsConfigOption;
use Shlinkio\Shlink\Installer\Config\Option\Redis\RedisServersConfigOption;
use Symfony\Component\Console\Style\StyleInterface;

class RedisDecodeCredentialsConfigOptionTest extends TestCase
{
private RedisDecodeCredentialsConfigOption $configOption;

public function setUp(): void
{
$this->configOption = new RedisDecodeCredentialsConfigOption();
}

#[Test]
public function returnsExpectedConfig(): void
{
self::assertEquals('REDIS_DECODE_CREDENTIALS', $this->configOption->getEnvVar());
}

#[Test]
public function expectedQuestionIsAsked(): void
{
$io = $this->createMock(StyleInterface::class);
$io->expects($this->once())->method('confirm')->with(
'Do you want redis credentials to be URL-decoded? '
. '(If you provided servers with URL-encoded credentials, this should be "yes")',
false,
)->willReturn(true);

$answer = $this->configOption->ask($io, []);

self::assertEquals(true, $answer);
}

#[Test, DataProvider('provideCurrentOptions')]
public function shouldBeCalledOnlyIfItDoesNotYetExist(array $currentOptions, bool $expected): void
{
self::assertEquals($expected, $this->configOption->shouldBeAsked($currentOptions));
}

public static function provideCurrentOptions(): iterable
{
yield 'not exists in config' => [[], false];
yield 'exists in config' => [['REDIS_DECODE_CREDENTIALS' => true], false];
yield 'redis enabled in config' => [[RedisServersConfigOption::ENV_VAR => 'bar'], true];
}

#[Test]
public function dependsOnRedisServer(): void
{
self::assertEquals(RedisServersConfigOption::class, $this->configOption->getDependentOption());
}
}
3 changes: 2 additions & 1 deletion test/Config/Option/Redis/RedisServersConfigOptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public function serversAreRequestedWhenRedisConfigIsProvided(?string $serversAns
false,
)->willReturn(true);
$this->io->expects($this->once())->method('ask')->with(
'Provide a comma-separated list of URIs (redis servers/sentinel instances)',
'Provide a comma-separated list of URIs (redis servers/sentinel instances). If they contains credentials '
. 'with URL-reserved chars, make sure they are URL-encoded',
)->willReturn($serversAnswer);

$result = $this->configOption->ask($this->io, []);
Expand Down

0 comments on commit dc6965c

Please sign in to comment.