From 34b99965c8c80ded80f06b68e396c40b6ff46fde Mon Sep 17 00:00:00 2001 From: Brandon Dunne Date: Thu, 17 Oct 2024 16:40:16 -0400 Subject: [PATCH] Add a migration to encrypt database password using scram-sha-256 CP4AIOPS-3003 --- ...41017013023_reencrypt_password_scramsha.rb | 13 +++++++++++ ...013023_reencrypt_password_scramsha_spec.rb | 22 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 db/migrate/20241017013023_reencrypt_password_scramsha.rb create mode 100644 spec/migrations/20241017013023_reencrypt_password_scramsha_spec.rb diff --git a/db/migrate/20241017013023_reencrypt_password_scramsha.rb b/db/migrate/20241017013023_reencrypt_password_scramsha.rb new file mode 100644 index 00000000..4595dd7e --- /dev/null +++ b/db/migrate/20241017013023_reencrypt_password_scramsha.rb @@ -0,0 +1,13 @@ +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 + username = db_config[:username] + password = connection.raw_connection.encrypt_password(db_config[:password], username, "scram-sha-256") + + connection.execute <<-SQL + ALTER ROLE #{username} WITH PASSWORD '#{password}'; + SQL + end + end +end diff --git a/spec/migrations/20241017013023_reencrypt_password_scramsha_spec.rb b/spec/migrations/20241017013023_reencrypt_password_scramsha_spec.rb new file mode 100644 index 00000000..1f293931 --- /dev/null +++ b/spec/migrations/20241017013023_reencrypt_password_scramsha_spec.rb @@ -0,0 +1,22 @@ +require_migration + +# This is mostly necessary for data migrations, so feel free to delete this +# file if you do no need it. +describe ReencryptPasswordScramsha do + migration_context :up do + it "Ensures that the user password is stored as scram-sha-256" do + migrate + + 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 + + record = users_and_passwords.to_a.detect { |i| i["rolname"] == username } + + expect(record["rolname"]).to eq(username) + expect(record["rolpassword"]).to match(/^SCRAM-SHA-256.*/) + end + end +end