Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save scottbaggett/3780472 to your computer and use it in GitHub Desktop.

Select an option

Save scottbaggett/3780472 to your computer and use it in GitHub Desktop.
comments.rb
Never hardcode sensitive information (account credentials, passwords, etc.) into your code. Instead, create a file to store that information as environment variables (key/value pairs), and exclude the file from your source code management system. For example, in terms of Git, .gitignore that file:
-bash> echo "config/app_environment_variables.rb" >> .gitignore
config/app_environment_variables.rb
ENV['HTTP_USER'] = 'devuser'
ENV['HTTP_PASS'] = 'devpass'
As well, add the following lines to config/environment.rb, between the require line, and the Application.initialize line:
# Load the app's custom environment variables here, so that they are loaded before environments/*.rb
app_environment_variables = File.join(Rails.root, 'config', 'app_environment_variables.rb')
load(app_environment_variables) if File.exists?(app_environment_variables)
As the comment says, by doing this, you will be loading your environment variables before environments/*.rb, which means that you will be able to refer to your variables inside those files (e.g. environments/production.rb). This is a great advantage over putting your environment variables file inside config/initializers/.
Inside app_environment_variables.rb there's no need to distinguish environments as far as development or production, because you will never check this file into your source code management system, hence it is essentially just for the development context. But if you need to set something special for the test environment, just add a conditional block below all the other variables:
if Rails.env.test?
ENV['HTTP_USER'] = "testuser"
ENV['HTTP_PASS'] = "testpass"
end
Whenever you update app_environment_variables.rb, restart the server:
-bash> touch tmp/restart.txt
In your code, just refer to the variables as follows:
def authenticate
authenticate_or_request_with_http_basic do |username, password|
username == ENV['HTTP_USER'] && password == ENV['HTTP_PASS']
end
end
If you have a single environment on Heroku:
-bash> heroku config:add HTTP_USER='herouser'
-bash> heroku config:add HTTP_USER='heropass'
If you have multiple environments on Heroku:
-bash> heroku config:add HTTP_USER='staguser' --remote staging
-bash> heroku config:add HTTP_PASS='stagpass' --remote staging
-bash> heroku config:add HTTP_USER='produser' --remote production
-bash> heroku config:add HTTP_PASS='prodpass' --remote production
Then, the final knot to tie is: how to share this sensitive information with your clients and/or partners? For the purpose of business continuity (i.e. when you get hit by a falling star, how will your clients and/or partners resume full operations of the site?), your clients and/or partners need to know all the credentials required by your app. Emailing/Skyping these things around is insecure and leads to disarray. Putting it in Google Docs is not bad (if everyone uses https), but I prefer a dedicated cloud-based solution for this, called Strongbox (https://www.strongbox.io/). With it, I create a new "box" for every app I am responsible for, and within each box, a new "item" for each service I sign up for (Heroku, Amazon, Google/Gmail, Google Apps etc.). As well, I create an "item" called "app environment variables", in which I create fields for all the environment variables (one field per variable). Then I share the box with my clients and/or partners. Changing ownership of boxes is not yet possible, so depending on the situation sometimes I get the client to create the box first and then share it with me and my dev partners.
Note that inside app_environment_variables.rb you must specify booleans and numbers as strings (e.g. ENV['SEND_MAIL'] = 'false' not just false, and ENV['TIMEOUT'] = '30' not just 30), otherwise you will get the errors can't convert false into String and can't convert Fixnum into String, respectively.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment