diff --git a/CHANGELOG.md b/CHANGELOG.md index 37b3b89c..276f5c1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,12 @@ Unreleased Changes * Issue - `ActionDispatch::Session::DynamoDbStore` now inherits `ActionDispatch::Session::AbstractStore` by wrapping `Aws::SessionStore::DynamoDB::RackMiddleware`. +* Issue - `DynamoDbStore` is now configured with the `:dynamo_db_store` configuration instead of `:dynamodb_store`. + +* Feature - `DYNAMO_DB_SESSION_CONFIG_FILE` is now searched and with precedence over the default Rails configuration YAML file locations. + +* Feature - Session Store configuration passed into `:dynamo_db_store` will now be considered when using the ActiveRecord migrations or rake tasks that create, delete, or clean session tables. + * Issue - Do not skip autoload modules for `Aws::Rails.instrument_sdk_operations`. 4.1.0 (2024-09-27) diff --git a/lib/action_dispatch/session/dynamo_db_store.rb b/lib/action_dispatch/session/dynamo_db_store.rb index 271852bf..bfc02943 100644 --- a/lib/action_dispatch/session/dynamo_db_store.rb +++ b/lib/action_dispatch/session/dynamo_db_store.rb @@ -50,7 +50,8 @@ def delete_session(req, sid, options) end def config_file - file = Rails.root.join("config/dynamo_db_session_store/#{Rails.env}.yml") + file = ENV.fetch('DYNAMO_DB_SESSION_CONFIG_FILE', nil) + file ||= Rails.root.join("config/dynamo_db_session_store/#{Rails.env}.yml") file = Rails.root.join('config/dynamo_db_session_store.yml') unless File.exist?(file) file if File.exist?(file) end diff --git a/lib/generators/dynamo_db/session_store_migration/templates/session_store_migration.erb b/lib/generators/dynamo_db/session_store_migration/templates/session_store_migration.erb index 6dff12f3..3959f135 100644 --- a/lib/generators/dynamo_db/session_store_migration/templates/session_store_migration.erb +++ b/lib/generators/dynamo_db/session_store_migration/templates/session_store_migration.erb @@ -2,10 +2,12 @@ class <%= name.camelize %> < ActiveRecord::Migration[<%= migration_version %>] def up - Aws::SessionStore::DynamoDB::Table.create_table + options = Rails.application.config.session_options + Aws::SessionStore::DynamoDB::Table.create_table(options) end def down - Aws::SessionStore::DynamoDB::Table.delete_table + options = Rails.application.config.session_options + Aws::SessionStore::DynamoDB::Table.delete_table(options) end end diff --git a/lib/tasks/dynamo_db/session_store.rake b/lib/tasks/dynamo_db/session_store.rake index f022d53c..ec22055c 100644 --- a/lib/tasks/dynamo_db/session_store.rake +++ b/lib/tasks/dynamo_db/session_store.rake @@ -4,17 +4,20 @@ namespace 'dynamo_db' do namespace 'session_store' do desc 'Create the Amazon DynamoDB session store table' task create_table: :environment do - Aws::SessionStore::DynamoDB::Table.create_table + options = Rails.application.config.session_options + Aws::SessionStore::DynamoDB::Table.create_table(options) end desc 'Delete the Amazon DynamoDB session store table' task delete_table: :environment do - Aws::SessionStore::DynamoDB::Table.delete_table + options = Rails.application.config.session_options + Aws::SessionStore::DynamoDB::Table.delete_table(options) end desc 'Clean up old sessions in the Amazon DynamoDB session store table' task clean: :environment do - Aws::SessionStore::DynamoDB::GarbageCollection.collect_garbage + options = Rails.application.config.session_options + Aws::SessionStore::DynamoDB::GarbageCollection.collect_garbage(options) end end end diff --git a/sample-app/db/migrate/20241028193427_create_dynamo_db_sessions_table.rb b/sample-app/db/migrate/20241028193427_create_dynamo_db_sessions_table.rb deleted file mode 100644 index b02603cc..00000000 --- a/sample-app/db/migrate/20241028193427_create_dynamo_db_sessions_table.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -class CreateDynamoDbSessionsTable < ActiveRecord::Migration[7.2] - def up - Aws::SessionStore::DynamoDB::Table.create_table - end - - def down - Aws::SessionStore::DynamoDB::Table.delete_table - end -end diff --git a/sample-app/db/migrate/20241106152613_create_dynamo_db_sessions_table.rb b/sample-app/db/migrate/20241106152613_create_dynamo_db_sessions_table.rb new file mode 100644 index 00000000..a3438db0 --- /dev/null +++ b/sample-app/db/migrate/20241106152613_create_dynamo_db_sessions_table.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class CreateDynamoDbSessionsTable < ActiveRecord::Migration[7.2] + def up + options = Rails.application.config.session_options + Aws::SessionStore::DynamoDB::Table.create_table(options) + end + + def down + options = Rails.application.config.session_options + Aws::SessionStore::DynamoDB::Table.delete_table(options) + end +end diff --git a/sample-app/db/schema.rb b/sample-app/db/schema.rb index 8a99497e..f7d30f8a 100644 --- a/sample-app/db/schema.rb +++ b/sample-app/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 2024_10_28_193427) do +ActiveRecord::Schema[7.2].define(version: 2024_11_06_152613) do create_table "users", force: :cascade do |t| t.string "email" t.string "password_digest" diff --git a/sample-app/storage/development.sqlite3 b/sample-app/storage/development.sqlite3 index 9a59f074..189f5763 100644 Binary files a/sample-app/storage/development.sqlite3 and b/sample-app/storage/development.sqlite3 differ diff --git a/test/action_dispatch/session/dynamo_db_store_test.rb b/test/action_dispatch/session/dynamo_db_store_test.rb index 3ea8f238..0f1f89f6 100644 --- a/test/action_dispatch/session/dynamo_db_store_test.rb +++ b/test/action_dispatch/session/dynamo_db_store_test.rb @@ -11,13 +11,21 @@ class DynamoDbStoreTest < ActiveSupport::TestCase { dynamo_db_client: Aws::DynamoDB::Client.new(stub_responses: true) } end + def setup_env + ENV['DYNAMO_DB_SESSION_CONFIG_FILE'] = 'test/dummy/config/session_store.yml' + end + + def teardown_env + ENV.delete('DYNAMO_DB_SESSION_CONFIG_FILE') + end + it 'loads config file' do store = ActionDispatch::Session::DynamoDbStore.new(nil, options) config_file_path = store.config.config_file.to_s assert_match(/dynamo_db_session_store.yml/, config_file_path) end - it 'loads environment config file and with precedence' do + it 'loads environment specific config files with precedence' do # Set Rails.env to something else so the environment.yml file is loaded old_env = Rails.env Rails.env = 'development' @@ -30,19 +38,29 @@ class DynamoDbStoreTest < ActiveSupport::TestCase Rails.env = old_env end - it 'allows config file override' do + it 'loads a config file from the environment variable with precedence' do + setup_env + store = ActionDispatch::Session::DynamoDbStore.new(nil, options) + config_file_path = store.config.config_file.to_s + assert_match(/session_store.yml/, config_file_path) + teardown_env + end + + it 'allows overriding the config file at runtime with highest precedence' do + setup_env options[:config_file] = 'test/dummy/config/session_store.yml' store = ActionDispatch::Session::DynamoDbStore.new(nil, options) config_file_path = store.config.config_file.to_s assert_match(/session_store.yml/, config_file_path) + teardown_env end - it 'uses rails secret key base' do + it 'uses the rails secret key base' do store = ActionDispatch::Session::DynamoDbStore.new(nil, options) assert_equal store.config.secret_key, Rails.application.secret_key_base end - it 'allows secret key override' do + it 'allows for secret key to be overridden' do secret_key = 'SECRET_KEY' options[:secret_key] = secret_key store = ActionDispatch::Session::DynamoDbStore.new(nil, options) diff --git a/test/tasks/dynamo_db/session_store_rake_test.rb b/test/tasks/dynamo_db/session_store_rake_test.rb index fbcbecc0..c6051de5 100644 --- a/test/tasks/dynamo_db/session_store_rake_test.rb +++ b/test/tasks/dynamo_db/session_store_rake_test.rb @@ -9,6 +9,13 @@ class SessionStoreRakeTest < ActiveSupport::TestCase before do Rake.application.rake_require 'tasks/dynamo_db/session_store' Rake::Task.define_task(:environment) + # MiniTest has an issue with kwargs in 2.7 + # https://github.com/minitest/minitest/blob/master/lib/minitest/mock.rb#L293C8-L293C30 + ENV["MT_KWARGS_HAC\K"] = '1' if RUBY_VERSION < '3' + end + + after do + ENV.delete("MT_KWARGS_HAC\K") end # Functionality for these methods are tested in aws-sessionstore-dynamodb. @@ -23,7 +30,9 @@ def expect_mock(method, task) end mock = MiniTest::Mock.new - mock.expect(:call, nil) + # After removing ENV["MT_KWARGS_HAC\K"], this can be stronger by asserting + # Rails.application.config.session_options is passed to the method. + mock.expect(:call, nil, [Hash]) klass.stub(method, mock) { Rake.application.invoke_task task } assert_mock mock end