From 3a8d7150861c0b50723f13176fd4dd8b3cdab9be Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Tue, 13 Feb 2024 22:32:28 +0100 Subject: [PATCH 1/2] Remove deprecated symbols --- CHANGELOG.md | 3 +++ README.md | 6 ++---- functions/functions.php | 15 --------------- src/Cache/RedisFactory.php | 31 +++++++++++-------------------- test/Cache/RedisFactoryTest.php | 12 ++---------- 5 files changed, 18 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 223b65a..ddf1308 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this ### Removed * Remove `BackwardsCompatibleMonologProcessorDelegator`. +* Remove support for redis URIs with just a password in place of the username (like `tcp://password@1.2.3.4`). +* Remove support for non-URL-encoded credentials in redis URIs. +* Remove `json_decode` and `json_encode` functions. ### Fixed * *Nothing* diff --git a/README.md b/README.md index 68bd29f..610e20c 100644 --- a/README.md +++ b/README.md @@ -50,16 +50,15 @@ return [ 'redis' => [ 'servers' => [ + // These should be valid URIs. Make sure credentials are URL-encoded 'tcp://1.1.1.1:6379', 'tcp://2.2.2.2:6379', 'tcp://3.3.3.3:6379', - 'tcp://user:password@4.4.4.4:6379', // Redis ACL (https://redis.io/docs/management/security/acl/) + 'tcp://user:pass%40word@4.4.4.4:6379', // Redis ACL (https://redis.io/docs/management/security/acl/) 'tcp://:password@5.5.5.5:6379', // Redis security (https://redis.io/docs/management/security/) - 'tcp://password@6.6.6.6:6379', // Same as above, but it's deprecated, as it's not a standard URI 'tls://server_with_encryption:6379', ], 'sentinel_service' => 'the_service', // Optional. - 'decode_credentials' => true // Optional. Defaults to false ], ], @@ -72,7 +71,6 @@ You can allow caching to be done on a redis instance, redis cluster or redis sen * `servers`: A list of redis servers. If one is provided, it will be treated as a single instance, and otherwise, a cluster will be assumed. * `sentinel_service`: Lets you enable sentinel mode. When provided, the servers will be treated as sentinel instances. -* `decode_credentials`: Indicates if server credentials (if present) should be URL decoded before passing to redis connection. Otherwise, they are passed verbatim. > **Note** > The entries in `servers` support credentials in the form of `tcp://password@my-server:6379` or `tcp://username:password@my-server:6379`. diff --git a/functions/functions.php b/functions/functions.php index be41688..d61bccc 100644 --- a/functions/functions.php +++ b/functions/functions.php @@ -5,25 +5,10 @@ namespace Shlinkio\Shlink\Common; use Cake\Chronos\Chronos; -use JsonSerializable; use Shlinkio\Shlink\Common\Util\DateRange; use function array_pad; use function explode; -use function Shlinkio\Shlink\Json\json_decode as shlink_json_decode; -use function Shlinkio\Shlink\Json\json_encode as shlink_json_encode; - -/** @deprecated Use the same function from shlinkio/shlink-json */ -function json_decode(string $json): array -{ - return shlink_json_decode($json); -} - -/** @deprecated Use the same function from shlinkio/shlink-json */ -function json_encode(array|JsonSerializable $payload): string -{ - return shlink_json_encode($payload); -} function buildDateRange(?Chronos $startDate, ?Chronos $endDate): DateRange { diff --git a/src/Cache/RedisFactory.php b/src/Cache/RedisFactory.php index d905862..3f9ca15 100644 --- a/src/Cache/RedisFactory.php +++ b/src/Cache/RedisFactory.php @@ -35,10 +35,9 @@ public function __invoke(ContainerInterface $container): PredisClient private function resolveServers(array $redisConfig): array { $servers = $redisConfig['servers'] ?? []; - $decodeCredentials = $redisConfig['decode_credentials'] ?? false; $servers = array_map( - fn (string $server) => $this->normalizeServer($server, $decodeCredentials), + fn (string $server) => $this->normalizeServer($server), is_string($servers) ? explode(',', $servers) : $servers, ); @@ -46,7 +45,7 @@ private function resolveServers(array $redisConfig): array return count($servers) === 1 ? $servers[0] : $servers; } - private function normalizeServer(string $server, bool $decodeCredentials): array + private function normalizeServer(string $server): array { $parsedServer = parse_url(trim($server)); if (! is_array($parsedServer)) { @@ -62,25 +61,17 @@ private function normalizeServer(string $server, bool $decodeCredentials): array $parsedServer['ssl'] = SSL::OPTIONS; } - if (! isset($parsedServer['user']) && ! isset($parsedServer['pass'])) { - return $parsedServer; - } + // Set credentials if set + $user = $parsedServer['user'] ?? null; + $pass = $parsedServer['pass'] ?? null; + unset($parsedServer['user'], $parsedServer['pass']); - // Deprecated. Apply URL decoding only if explicitly requested, for BC. Next major version will always do it - $credentialsCallback = static fn (string $val) => ($decodeCredentials ? urldecode($val) : $val); - - if (isset($parsedServer['user']) && ! isset($parsedServer['pass'])) { - // For historical reasons, we support URLs in the form of `tcp://redis_password@redis_host:1234`, but this - // is deprecated - $parsedServer['password'] = $credentialsCallback($parsedServer['user']); - } elseif (isset($parsedServer['user'], $parsedServer['pass'])) { - if ($parsedServer['user'] !== '') { - $parsedServer['username'] = $credentialsCallback($parsedServer['user']); - } - $parsedServer['password'] = $credentialsCallback($parsedServer['pass']); + if ($user !== null && $user !== '') { + $parsedServer['username'] = urldecode($user); + } + if ($pass !== null) { + $parsedServer['password'] = urldecode($pass); } - - unset($parsedServer['user'], $parsedServer['pass']); return $parsedServer; } diff --git a/test/Cache/RedisFactoryTest.php b/test/Cache/RedisFactoryTest.php index 66daf8e..c72e302 100644 --- a/test/Cache/RedisFactoryTest.php +++ b/test/Cache/RedisFactoryTest.php @@ -144,19 +144,11 @@ public static function provideServersWithCredentials(): iterable yield 'password only' => [[ 'servers' => ['tcp://:baz@1.1.1.1:6379'], ], null, 'baz', null]; - yield 'password only (deprecated)' => [[ + yield 'username only' => [[ 'servers' => ['tcp://foo@1.1.1.1:6379'], - ], null, 'foo', null]; + ], 'foo', null, null]; yield 'URL-encoded' => [[ 'servers' => ['tcp://user%3Aname:pass%40word@1.1.1.1:6379'], - ], 'user%3Aname', 'pass%40word', null]; - yield 'URL-encoded, no request decode' => [[ - 'servers' => ['tcp://user%3Aname:pass%40word@1.1.1.1:6379'], - 'decode_credentials' => false, - ], 'user%3Aname', 'pass%40word', null]; - yield 'URL-encoded, request decode' => [[ - 'servers' => ['tcp://user%3Aname:pass%40word@1.1.1.1:6379'], - 'decode_credentials' => true, ], 'user:name', 'pass@word', null]; yield 'tls encryption' => [[ 'servers' => ['tls://1.1.1.1:6379'], From 58dc6a117d5064d02d4818ed0c411ab5a1f89047 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Tue, 13 Feb 2024 22:35:13 +0100 Subject: [PATCH 2/2] Remove no-longer needed PHPStan supression --- src/RabbitMq/AMQPConnectionFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RabbitMq/AMQPConnectionFactory.php b/src/RabbitMq/AMQPConnectionFactory.php index dd0881c..d2b553a 100644 --- a/src/RabbitMq/AMQPConnectionFactory.php +++ b/src/RabbitMq/AMQPConnectionFactory.php @@ -37,7 +37,7 @@ public function __invoke(ContainerInterface $container): AMQPStreamConnection // We have to pass the config as the ssl_protocol to avoid an internal deprecation warning // When the ssl_protocol is a config instance, it is internally set as config. // See https://github.com/php-amqplib/php-amqplib/blob/b4ade54ebe4685873f6316f9a05fc2c77a9e28f9/PhpAmqpLib/Connection/AMQPStreamConnection.php#L48-L55 - ssl_protocol: $connectionConfig, // @phpstan-ignore-line + ssl_protocol: $connectionConfig, ); }