mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
94d1d52c03
In a new Rails app, the generated credentials file contains an example of some [nested secrets](f95c0b7e96/railties/lib/rails/generators/rails/credentials/credentials_generator.rb (L46)
).
Currently you can't access them nicely the way you would top level secrets:
```
2.7.3 :001 > Rails.application.credentials.aws
=> {:access_key_id=>123, :secret_access_key=>345}
2.7.3 :002 > Rails.application.credentials.aws.access_key_id
Traceback (most recent call last):
1: from (irb):2
NoMethodError (undefined method `access_key_id' for {:access_key_id=>123, :secret_access_key=>345}:Hash)
2.7.3 :003 > Rails.application.credentials.secret_key_base
=> "abcd..."
```
It would make secrets easier to use if you could, so this PR adds support for that. `Rails.application.credentials.aws.access_key_id` will now return `123` in the above example.
49 lines
1.3 KiB
Ruby
49 lines
1.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "yaml"
|
|
require "active_support/encrypted_file"
|
|
require "active_support/ordered_options"
|
|
require "active_support/core_ext/object/inclusion"
|
|
require "active_support/core_ext/module/delegation"
|
|
|
|
module ActiveSupport
|
|
class EncryptedConfiguration < EncryptedFile
|
|
delegate :[], :fetch, to: :config
|
|
delegate_missing_to :options
|
|
|
|
def initialize(config_path:, key_path:, env_key:, raise_if_missing_key:)
|
|
super content_path: config_path, key_path: key_path,
|
|
env_key: env_key, raise_if_missing_key: raise_if_missing_key
|
|
end
|
|
|
|
# Allow a config to be started without a file present
|
|
def read
|
|
super
|
|
rescue ActiveSupport::EncryptedFile::MissingContentError
|
|
""
|
|
end
|
|
|
|
def write(contents)
|
|
deserialize(contents)
|
|
|
|
super
|
|
end
|
|
|
|
def config
|
|
@config ||= deserialize(read).deep_symbolize_keys
|
|
end
|
|
|
|
private
|
|
def deep_transform(hash)
|
|
hash.transform_values { |value| value.is_a?(Hash) ? ActiveSupport::InheritableOptions.new(deep_transform(value)) : value }
|
|
end
|
|
|
|
def options
|
|
@options ||= ActiveSupport::InheritableOptions.new(deep_transform(config))
|
|
end
|
|
|
|
def deserialize(config)
|
|
YAML.load(config).presence || {}
|
|
end
|
|
end
|
|
end
|