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