From 742841cf8954be1cb5843dca33945b5fc001cf8d Mon Sep 17 00:00:00 2001 From: Brandon Dunne Date: Thu, 24 Oct 2024 12:19:26 -0400 Subject: [PATCH] Handle cases where the database connection does not use a password --- ...41017013023_reencrypt_password_scramsha.rb | 2 ++ ...013023_reencrypt_password_scramsha_spec.rb | 27 ++++++++++++++----- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/db/migrate/20241017013023_reencrypt_password_scramsha.rb b/db/migrate/20241017013023_reencrypt_password_scramsha.rb index 4595dd7e..8764fd10 100644 --- a/db/migrate/20241017013023_reencrypt_password_scramsha.rb +++ b/db/migrate/20241017013023_reencrypt_password_scramsha.rb @@ -2,6 +2,8 @@ class ReencryptPasswordScramsha < ActiveRecord::Migration[6.1] def up say_with_time('Reencrypting database user password with scram-sha-256') do db_config = ActiveRecord::Base.connection_db_config.configuration_hash + return if db_config[:username].blank? || db_config[:password].blank? + username = db_config[:username] password = connection.raw_connection.encrypt_password(db_config[:password], username, "scram-sha-256") diff --git a/spec/migrations/20241017013023_reencrypt_password_scramsha_spec.rb b/spec/migrations/20241017013023_reencrypt_password_scramsha_spec.rb index 1f293931..5bacb2f7 100644 --- a/spec/migrations/20241017013023_reencrypt_password_scramsha_spec.rb +++ b/spec/migrations/20241017013023_reencrypt_password_scramsha_spec.rb @@ -5,18 +5,31 @@ describe ReencryptPasswordScramsha do migration_context :up do it "Ensures that the user password is stored as scram-sha-256" do - migrate + allow(ActiveRecord::Base.connection).to receive(:execute).and_call_original username = ActiveRecord::Base.connection_db_config.configuration_hash[:username] - users_and_passwords = ActiveRecord::Base.connection.execute <<-SQL - SELECT rolname, rolpassword FROM pg_authid WHERE rolcanlogin; - SQL + expect(ActiveRecord::Base.connection_db_config).to receive(:configuration_hash).exactly(10).times.and_call_original + expect(ActiveRecord::Base.connection_db_config).to receive(:configuration_hash).and_wrap_original do |original_method, *args, &block| + original_method.call(*args, &block).dup.tap { |i| i[:password] ||= "abc" } + end + expect(ActiveRecord::Base.connection).to receive(:execute).with(a_string_matching(/ALTER ROLE #{username} WITH PASSWORD \'SCRAM-SHA-256.*\'\;/)) + + migrate + end + + it "Handles connections with no password" do + allow(ActiveRecord::Base.connection).to receive(:execute).and_call_original + + username = ActiveRecord::Base.connection_db_config.configuration_hash[:username] - record = users_and_passwords.to_a.detect { |i| i["rolname"] == username } + expect(ActiveRecord::Base.connection_db_config).to receive(:configuration_hash).exactly(10).times.and_call_original + expect(ActiveRecord::Base.connection_db_config).to receive(:configuration_hash).and_wrap_original do |original_method, *args, &block| + original_method.call(*args, &block).dup.tap { |i| i.delete(:password) } + end + expect(ActiveRecord::Base.connection).not_to receive(:execute).with(a_string_matching(/ALTER ROLE.*\'\;/)) - expect(record["rolname"]).to eq(username) - expect(record["rolpassword"]).to match(/^SCRAM-SHA-256.*/) + migrate end end end