From e5cb2091597cbad90d18327955df4e34865535c5 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 | 23 +++++++++++++++++++ 2 files changed, 36 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..fdee0495 --- /dev/null +++ b/spec/migrations/20241017013023_reencrypt_password_scramsha_spec.rb @@ -0,0 +1,23 @@ +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 + + users_and_passwords = execute <<-SQL + SELECT rolname, rolpassword FROM pg_authid WHERE rolcanlogin; + SQL + + database_yml = YAML.safe_load(Rails.root.join("config", "database.yml")) + username = database_yml[Rails.env]["username"] + + 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