Module: Railsmdb::Generators::Setup::Concerns::Setuppable Private

Extended by:
ActiveSupport::Concern
Includes:
Prioritizable
Included in:
Rails::Generators::AppGenerator, Railsmdb::Generators::SetupGenerator
Defined in:
lib/railsmdb/generators/setup/concerns/setuppable.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Tasks used for configuring a Rails app to use Mongoid, including adding support for encryption. This concern is shared between the app generator (e.g. ‘railsmdb new`) and the setup generator (e.g. `railsmdb setup`).

Constant Summary collapse

GemfileEntry =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Rails::Generators::AppBase::GemfileEntry
KEY_VAULT_CONFIG =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

<<~CONFIG
  # This client is used to obtain the encryption keys from the key vault.
  # For security reasons, this should be a different database instance than
  # your primary application database.
  key_vault:
    uri: mongodb://localhost:27017

CONFIG
AUTO_ENCRYPTION_CONFIG =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

<<~CONFIG.freeze
  # You can read about the auto encryption options here:
  # https://www.mongodb.com/docs/ruby-driver/v#{Mongo::VERSION.split('.').first(2).join('.')}/reference/in-use-encryption/client-side-encryption/#auto-encryption-options
  auto_encryption_options:
    key_vault_client: 'key_vault'
    key_vault_namespace: 'encryption.__keyVault'
    kms_providers:
      # Using a local master key is insecure and is not recommended if you plan
      # to use client-side encryption in production.
      #
      # To learn how to set up a remote Key Management Service, see the tutorials
      # at https://www.mongodb.com/docs/manual/core/csfle/tutorials/.
      local:
        key: '<%= Rails.application.credentials.mongodb_master_key %>'
    extra_options:
      crypt_shared_lib_path: %crypt-shared-path%

CONFIG
PRELOAD_MODELS_OPTION =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

<<~CONFIG
  #
  # Setting it to true is recommended for auto encryption to work
  # properly in development.
  preload_models: true
CONFIG

Instance Method Summary collapse

Instance Method Details

#add_encryption_options_to_mongoid_ymlObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

If encryption is enabled, update the mongoid.yml with the necessary options for encryption.



160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/railsmdb/generators/setup/concerns/setuppable.rb', line 160

def add_encryption_options_to_mongoid_yml
  return unless @okay_to_support_encryption

  mongoid_yml = File.join(Dir.pwd, 'config/mongoid.yml')
  contents = File.read(mongoid_yml)

  contents = insert_key_vault_config(contents)
  contents = insert_auto_encryption_options(contents)
  contents = insert_preload_models_option(contents)

  say_status :update, 'config/mongoid.yml'
  File.write(mongoid_yml, contents)
end

#add_mongodb_local_master_key_to_credentialsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Appends a new local master key to the credentials file



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/railsmdb/generators/setup/concerns/setuppable.rb', line 141

def add_mongodb_local_master_key_to_credentials
  return unless @okay_to_support_encryption

  say_status :append, CREDENTIALS_FILE_PATH

  credentials_file.change do |tmp_path|
    File.open(tmp_path, 'a') do |io|
      io.puts
      io.puts '# Master key for MongoDB auto encryption'
      # passing `96 / 2` because we need a 96-byte key, but
      # SecureRandom.hex returns a hex-encoded string, which will
      # be two bytes for requested byte.
      io.puts "mongodb_master_key: '#{SecureRandom.hex(96 / 2)}'"
    end
  end
end

#add_mongoid_gem_entriesObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Appends the mongoid gem entries to the Gemfile.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/railsmdb/generators/setup/concerns/setuppable.rb', line 116

def add_mongoid_gem_entries
  mongoid_gem_entries.each do |group, list|
    append_to_file 'Gemfile' do
      prefix = group ? "\ngroup :#{group} do\n" : "\n"
      suffix = group ? "\nend\n" : "\n"
      indent_size = group ? 2 : 0

      prefix +
        list.map { |entry| indent_entry(entry, indent_size) }
            .join("\n\n") +
        suffix
    end
  end
end

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks to see if the user agrees to the encryption terms and conditions



91
92
93
94
95
96
97
# File 'lib/railsmdb/generators/setup/concerns/setuppable.rb', line 91

def confirm_legal_shenanigans
  return unless options[:encryption]

  @okay_to_support_encryption =
    options[:accept_customer_agreement] ||
    okay_with_legal_shenanigans?
end

#fetch_crypt_sharedObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Fetches the MongoDB crypt_shared library and stores it in vendor/crypt_shared.



101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/railsmdb/generators/setup/concerns/setuppable.rb', line 101

def fetch_crypt_shared
  return unless @okay_to_support_encryption

  log :fetch, 'current MongoDB catalog'
  catalog = Railsmdb::CryptShared::Catalog.current
  url, sha = catalog.optimal_download_url_for_this_host

  if url
    fetch_and_extract_crypt_shared_from_url(url, sha)
  else
    say_error 'Cannot find download URL for crypt_shared, for this host'
  end
end

#mongoid_initializerObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emit the mongoid.rb initializer. Unlike mongoid.yml, this is not taken from the mongoid gem, because mongoid versions prior to 9 did not include an initializer template.



177
178
179
# File 'lib/railsmdb/generators/setup/concerns/setuppable.rb', line 177

def mongoid_initializer
  template '_config/initializers/mongoid.rb', 'config/initializers/mongoid.rb'
end

#mongoid_ymlObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emit the mongoid.yml file to the new application folder. The mongoid.yml file is taken directly from the installed mongoid gem.



134
135
136
137
138
# File 'lib/railsmdb/generators/setup/concerns/setuppable.rb', line 134

def mongoid_yml
  file = Gem.find_files('rails/generators/mongoid/config/templates/mongoid.yml').first
  database_name = app_name
  template file, 'config/mongoid.yml', context: binding
end

#railsmdbObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emit the bin/railsmdb script to the new app’s bin folder. The existing bin/rails script is removed, and replaced by a link to bin/railsmdb.



184
185
186
187
188
189
190
191
192
193
# File 'lib/railsmdb/generators/setup/concerns/setuppable.rb', line 184

def railsmdb
  template '_bin/railsmdb', 'bin/railsmdb' do |content|
    "#{shebang}\n" + content
  end

  chmod 'bin/railsmdb', 0o755, verbose: false

  remove_file 'bin/rails', verbose: false
  create_link 'bin/rails', File.expand_path('bin/railsmdb', destination_root), verbose: false
end

#save_initial_pathObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Save the current directory; this way, we can see if it is being run from the railsmdb project directory, in development, and set up the railsmdb gem dependency appropriately.



86
87
88
# File 'lib/railsmdb/generators/setup/concerns/setuppable.rb', line 86

def save_initial_path
  @initial_path = Dir.pwd
end