diff --git a/db/migrate/20241017013023_reencrypt_password_scramsha.rb b/db/migrate/20241017013023_reencrypt_password_scramsha.rb new file mode 100644 index 00000000..16e5db19 --- /dev/null +++ b/db/migrate/20241017013023_reencrypt_password_scramsha.rb @@ -0,0 +1,17 @@ +class ReencryptPasswordScramsha < ActiveRecord::Migration[6.1] + def up + say_with_time('Reencrypting database user password with scram-sha-256') do + database_yml = YAML.safe_load(Rails.root.join("config", "database.yml")) + username = database_yml[Rails.env]["username"] + password = MiqPassword.try_decrypt(database_yml[Rails.env]["password"]) + + execute <<-SQL + SET password_encryption='scram-sha-256'; + SQL + + 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