From 362c8c6bd9c6edffd5befb55560cc12207144cf5 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Fri, 15 Oct 2021 19:51:51 +0200 Subject: [PATCH] Restore Redis 4.3.0 accidental AUTH fallback behavior with a deprecation warning --- CHANGELOG.md | 4 ++++ lib/redis/client.rb | 10 ++++++++++ test/connection_test.rb | 28 ++++++++++++++++++++++++++++ test/helper.rb | 10 ++++++++++ 4 files changed, 52 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7296dccfb..979004d2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Unreleased +* Restore the accidential auth behavior of redis-rb 4.3.0 with a warning. If provided with the `default` user password, but a wrong username, + redis-rb will first try to connect as the provided user, but then will fallback to connect as the `default` user with the provided password. + This behavior is deprecated and will be removed in Redis 4.6.0. Fix #1038. + # 4.5.0 * Handle parts of the command using incompatible encodings. See #1037. diff --git a/lib/redis/client.rb b/lib/redis/client.rb index d480020c6..69cbe4de2 100644 --- a/lib/redis/client.rb +++ b/lib/redis/client.rb @@ -122,6 +122,16 @@ def connect rescue CommandError => err # Likely on Redis < 6 if err.message.match?(/ERR wrong number of arguments for \'auth\' command/) call [:auth, password] + elsif err.message.match?(/WRONGPASS invalid username-password pair/) + begin + call [:auth, password] + rescue CommandError + raise err + end + ::Kernel.warn( + "[redis-rb] The Redis connection was configured with username #{username.inspect}, but" \ + " the provided password was for the default user. This will start failing in redis-rb 4.6." + ) else raise end diff --git a/test/connection_test.rb b/test/connection_test.rb index 933bd6155..5c8bf6009 100644 --- a/test/connection_test.rb +++ b/test/connection_test.rb @@ -9,6 +9,34 @@ def test_provides_a_meaningful_inspect assert_equal "#", r.inspect end + def test_connection_with_user_and_password + target_version "6.0" do + with_acl do |username, password| + redis = Redis.new(OPTIONS.merge(username: username, password: password)) + assert_equal "PONG", redis.ping + end + end + end + + def test_connection_with_default_user_and_password + target_version "6.0" do + with_default_user_password do |_username, password| + redis = Redis.new(OPTIONS.merge(password: password)) + assert_equal "PONG", redis.ping + end + end + end + + def test_connection_with_wrong_user_and_password + target_version "6.0" do + with_default_user_password do |_username, password| + Kernel.expects(:warn).once + redis = Redis.new(OPTIONS.merge(username: "does-not-exist", password: password)) + assert_equal "PONG", redis.ping + end + end + end + def test_connection_information assert_equal "127.0.0.1", r.connection.fetch(:host) assert_equal 6381, r.connection.fetch(:port) diff --git a/test/helper.rb b/test/helper.rb index 9d6edefa0..0a98354db 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -172,9 +172,19 @@ def with_acl '+ping', '+select', '+command', '+cluster|slots', '+cluster|nodes', '>mysecret') yield('johndoe', 'mysecret') + ensure admin.acl('DELUSER', 'johndoe') admin.close end + + def with_default_user_password + admin = _new_client + admin.acl('SETUSER', 'default', '>mysecret') + yield('default', 'mysecret') + ensure + admin.acl('SETUSER', 'default', 'nopass') + admin.close + end end module Client