123456789_123456789_123456789_123456789_123456789_

Class: Rails::Secrets

Do not use. This class is for internal use only.
Relationships & Source Files
Namespace Children
Exceptions:
Inherits: Object
Defined in: railties/lib/rails/secrets.rb

Overview

Greatly inspired by Ara T. Howard’s magnificent sekrets gem. 😘

Class Attribute Summary

Class Method Summary

Class Attribute Details

.root=(value) (writeonly)

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 23

attr_writer :root

Class Method Details

.decrypt(data)

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 46

def decrypt(data)
  encryptor.decrypt_and_verify(data)
end

.encrypt(data)

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 42

def encrypt(data)
  encryptor.encrypt_and_sign(data)
end

.encryptor (private)

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 105

def encryptor
  @encryptor ||= ActiveSupport::MessageEncryptor.new([ key ].pack("H*"), cipher: @cipher)
end

.handle_missing_key (private)

Raises:

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 64

def handle_missing_key
  raise MissingKeyError
end

.key

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 38

def key
  ENV["RAILS_MASTER_KEY"] || read_key_file || handle_missing_key
end

.key_path (private)

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 74

def key_path
  @root.join("config", "secrets.yml.key")
end

.parse(paths, env:)

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 25

def parse(paths, env:)
  paths.each_with_object(Hash.new) do |path, all_secrets|
    require "erb"

    source = ERB.new(preprocess(path)).result
    secrets = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(source) : YAML.load(source)
    secrets ||= {}

    all_secrets.merge!(secrets["shared"].deep_symbolize_keys) if secrets["shared"]
    all_secrets.merge!(secrets[env].deep_symbolize_keys) if secrets[env]
  end
end

.path (private)

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 78

def path
  @root.join("config", "secrets.yml.enc").to_s
end

.preprocess(path) (private)

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 82

def preprocess(path)
  if path.end_with?(".enc")
    decrypt(IO.binread(path))
  else
    IO.read(path)
  end
end

.read

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 50

def read
  decrypt(IO.binread(path))
end

.read_for_editing(&block)

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 59

def read_for_editing(&block)
  writing(read, &block)
end

.read_key_file (private)

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 68

def read_key_file
  if File.exist?(key_path)
    IO.binread(key_path).strip
  end
end

.write(contents)

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 54

def write(contents)
  IO.binwrite("#{path}.tmp", encrypt(contents))
  FileUtils.mv("#{path}.tmp", path)
end

.writing(contents) (private)

[ GitHub ]

  
# File 'railties/lib/rails/secrets.rb', line 90

def writing(contents)
  file_name = "#{File.basename(path)}.#{Process.pid}"

  Tempfile.create(["", "-" + file_name]) do |tmp_file|
    tmp_path = Pathname.new(tmp_file)
    tmp_path.binwrite contents

    yield tmp_path

    updated_contents = tmp_path.binread

    write(updated_contents) if updated_contents != contents
  end
end