Fixes for tests and AR Encryption
This commit is contained in:
@@ -6,17 +6,23 @@
|
|||||||
# - ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY
|
# - ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY
|
||||||
# - ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY
|
# - ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY
|
||||||
# - ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT
|
# - ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT
|
||||||
Rails.application.config.after_initialize do
|
|
||||||
# Use env vars if set, otherwise derive from SECRET_KEY_BASE (deterministic)
|
# Use env vars if set, otherwise derive from SECRET_KEY_BASE (deterministic)
|
||||||
primary_key = ENV['ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY'] || Rails.application.key_generator.generate_key('active_record_encryption_primary', 32)
|
primary_key = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY') do
|
||||||
deterministic_key = ENV['ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY'] || Rails.application.key_generator.generate_key('active_record_encryption_deterministic', 32)
|
Rails.application.key_generator.generate_key('active_record_encryption_primary', 32)
|
||||||
key_derivation_salt = ENV['ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT'] || Rails.application.key_generator.generate_key('active_record_encryption_salt', 32)
|
end
|
||||||
|
deterministic_key = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY') do
|
||||||
|
Rails.application.key_generator.generate_key('active_record_encryption_deterministic', 32)
|
||||||
|
end
|
||||||
|
key_derivation_salt = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT') do
|
||||||
|
Rails.application.key_generator.generate_key('active_record_encryption_salt', 32)
|
||||||
|
end
|
||||||
|
|
||||||
# Configure Rails 7.1+ ActiveRecord encryption
|
# Configure Rails 7.1+ ActiveRecord encryption
|
||||||
Rails.application.config.active_record.encryption.primary_key = primary_key
|
Rails.application.config.active_record.encryption.primary_key = primary_key
|
||||||
Rails.application.config.active_record.encryption.deterministic_key = deterministic_key
|
Rails.application.config.active_record.encryption.deterministic_key = deterministic_key
|
||||||
Rails.application.config.active_record.encryption.key_derivation_salt = key_derivation_salt
|
Rails.application.config.active_record.encryption.key_derivation_salt = key_derivation_salt
|
||||||
|
|
||||||
# Ensure encryption is enabled
|
# Allow unencrypted data for existing records (new/updated records will be encrypted)
|
||||||
Rails.application.config.active_record.encryption.support_unencrypted_data = false
|
# Set to false after all existing encrypted columns have been migrated
|
||||||
end
|
Rails.application.config.active_record.encryption.support_unencrypted_data = true
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ class OidcAccessTokenTest < ActiveSupport::TestCase
|
|||||||
user: users(:alice)
|
user: users(:alice)
|
||||||
)
|
)
|
||||||
|
|
||||||
assert access_token.plaintext_token.length > auth_code.code.length,
|
assert access_token.plaintext_token.length > auth_code.plaintext_code.length,
|
||||||
"Access tokens should be longer than authorization codes"
|
"Access tokens should be longer than authorization codes"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ class OidcAuthorizationCodeTest < ActiveSupport::TestCase
|
|||||||
user: users(:alice),
|
user: users(:alice),
|
||||||
redirect_uri: "https://example.com/callback"
|
redirect_uri: "https://example.com/callback"
|
||||||
)
|
)
|
||||||
assert_nil new_code.code
|
assert_nil new_code.code_hmac
|
||||||
assert new_code.save
|
assert new_code.save
|
||||||
assert_not_nil new_code.code
|
assert_not_nil new_code.code_hmac
|
||||||
assert_match /^[A-Za-z0-9_-]+$/, new_code.code
|
assert_match /^[a-f0-9]{64}$/, new_code.code_hmac # SHA256 hex digest
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should set expiry before validation on create" do
|
test "should set expiry before validation on create" do
|
||||||
@@ -44,22 +44,22 @@ class OidcAuthorizationCodeTest < ActiveSupport::TestCase
|
|||||||
assert new_code.expires_at <= 11.minutes.from_now # Allow some variance
|
assert new_code.expires_at <= 11.minutes.from_now # Allow some variance
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should validate presence of code" do
|
test "should validate presence of code_hmac" do
|
||||||
@auth_code.code = nil
|
@auth_code.code_hmac = nil
|
||||||
assert_not @auth_code.valid?
|
assert_not @auth_code.valid?
|
||||||
assert_includes @auth_code.errors[:code], "can't be blank"
|
assert_includes @auth_code.errors[:code_hmac], "can't be blank"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should validate uniqueness of code" do
|
test "should validate uniqueness of code_hmac" do
|
||||||
@auth_code.save! if @auth_code.changed?
|
@auth_code.save! if @auth_code.changed?
|
||||||
duplicate = OidcAuthorizationCode.new(
|
duplicate = OidcAuthorizationCode.new(
|
||||||
code: @auth_code.code,
|
code_hmac: @auth_code.code_hmac,
|
||||||
application: applications(:another_app),
|
application: applications(:another_app),
|
||||||
user: users(:bob),
|
user: users(:bob),
|
||||||
redirect_uri: "https://example.com/callback"
|
redirect_uri: "https://example.com/callback"
|
||||||
)
|
)
|
||||||
assert_not duplicate.valid?
|
assert_not duplicate.valid?
|
||||||
assert_includes duplicate.errors[:code], "has already been taken"
|
assert_includes duplicate.errors[:code_hmac], "has already been taken"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should validate presence of redirect_uri" do
|
test "should validate presence of redirect_uri" do
|
||||||
@@ -178,16 +178,16 @@ class OidcAuthorizationCodeTest < ActiveSupport::TestCase
|
|||||||
user: users(:alice),
|
user: users(:alice),
|
||||||
redirect_uri: "https://example.com/callback"
|
redirect_uri: "https://example.com/callback"
|
||||||
)
|
)
|
||||||
codes << code.code
|
codes << code.code_hmac
|
||||||
end
|
end
|
||||||
|
|
||||||
# All codes should be unique
|
# All codes should be unique
|
||||||
assert_equal codes.length, codes.uniq.length
|
assert_equal codes.length, codes.uniq.length
|
||||||
|
|
||||||
# All codes should match the expected pattern
|
# All codes should be SHA256 hex digests
|
||||||
codes.each do |code|
|
codes.each do |code|
|
||||||
assert_match /^[A-Za-z0-9_-]+$/, code
|
assert_match /^[a-f0-9]{64}$/, code
|
||||||
assert_equal 43, code.length # Base64 padding removed
|
assert_equal 64, code.length # SHA256 hex digest
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user