Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Env class to access environmental variables and encrypted credentials.
  • Loading branch information
Cong committed Dec 17, 2018
1 parent 3b900b5 commit 3886827
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 38 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -21,3 +21,6 @@

# SimpleCove code coverage report
coverage

# Ignore master key for decrypting credentials and more.
/config/master.key
66 changes: 64 additions & 2 deletions README.md
@@ -1,7 +1,7 @@
[![Maintainability](https://api.codeclimate.com/v1/badges/6bc16f3bcc5522f2b685/maintainability)](https://codeclimate.com/github/vochicong/rails-json-api/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/6bc16f3bcc5522f2b685/test_coverage)](https://codeclimate.com/github/vochicong/rails-json-api/test_coverage)

# README
# Rails API server

## 作業手順

Expand Down Expand Up @@ -108,7 +108,7 @@ Start Rails server

bin/rails db:migrate RAILS_ENV=development
rails s

Create users

curl http://localhost:3000/users -X POST -H "Content-Type: application/json" -d '{"fullName": "Michal Jackson", "emailAddress": "michale@gmail.com"}'
Expand All @@ -124,3 +124,65 @@ Get users
- [Postman](https://www.getpostman.com/)
- [DRY-ing The JSON Response](http://aalvarez.me/blog/posts/testing-a-rails-api-with-rspec.html)
- [Rails API Testing Best Practices](http://matthewlehner.net/rails-api-testing-guidelines/)

# Rails encrypted credentials

Rails 5.2 から `config/credentials.yml.enc` が導入され、混乱を招いている。
`development`, `test` では環境変数を使って、`production` (または `staging`など)で
`encrypted credentials` を使うニーズに手軽に対応するには、
`config/environment.rb` にクラス `Env`を導入してみた。

```ruby
class Env
def self.method_missing(name, *default)
ENV[name.to_s] ||
default.first ||
Rails.application.credentials.send(name) ||
super
end

def self.respond_to_missing?(*)
true
end
end
```

## 使い方

システム構成情報は、環境変数または`config/credentials.yml.enc`に設定する。
`Env.APP_CONFIG``APP_CONFIG` をまず
環境変数 `ENV` から探して、未設定の場合に `encrypted credentials` から探す。
引数にデフォルトの値が与えられたら、`encrypted credentials` からは探さない。

##

### config/credentials.yml.enc の内容確認

$ RAILS_MASTER_KEY=289e1431050b365b62bb5917acabcc53 rails credentials:show
secret_key_base: 2105bc31227a27f81b901582a8bb43b35bebea2b9c3572b024184a0b06dad26fc3bb312fbc5a7069783798d22f55cf4f411ae19169dd2a78026dccfbbdc889d7
APP_CONFIG: encryptedConfig

### 環境変数が未定義の場合、デフォルト値が使われる

$ rails runner 'puts Env.APP_CONFIG("default")'
default

### 環境変数がデフォルト値よりも優先される

$ APP_CONFIG=envVar rails runner 'puts Env.APP_CONFIG("default")'
envVar

### 環境変数が、`encrypted credentials` よりも優先される

$ RAILS_MASTER_KEY=289e1431050b365b62bb5917acabcc53 APP_CONFIG=envVar rails runner 'puts Env.APP_CONFIG("default")'
envVar

### デフォルト値が `encrypted credentials` よりも優先される

$ RAILS_MASTER_KEY=289e1431050b365b62bb5917acabcc53 rails runner 'puts Env.APP_CONFIG("default")'
default

### 環境変数もデフォルト値も未定義の場合、`encrypted credentials` が使われる

$ RAILS_MASTER_KEY=289e1431050b365b62bb5917acabcc53 rails runner 'puts Env.APP_CONFIG'
encryptedConfig
1 change: 1 addition & 0 deletions config/credentials.yml.enc
@@ -0,0 +1 @@
m7OMHqBx4GYQefvvNsCarRdeTk+nA+8YY6mZzFFXkxuQDMxvkeXwi3PagNlpX0JJsU/Bm+o7NtffZamPXVvCV+ZGeJ7mC+fY+IUZBMmuVAQfHWiGjCMKCe2j2veYzNbA59VBijYjHEppmkAu1fkMqigaqgO7eOpxZ8+hd23KFOlhGC5hOR5EjM6DUvn0dcJ8pk5Ny4uMeZdgVp5kp3b01dIpzXJygxDmtWsW/myeVoQfRLE=--Ly3MeODgN7+R63Se--nLrWbxLLIb9vWCjepKP4Ow==
17 changes: 17 additions & 0 deletions config/environment.rb
@@ -1,6 +1,23 @@
# Load the Rails application.
require_relative 'application'

# Environmental secret and configuration variables
# Env.APP_CONFIG(default) will look for APP_CONFIG
# from environment variables, the `default` value,
# and then from encrypted credentials.
class Env
def self.method_missing(name, *default)
ENV[name.to_s] ||
default.first ||
Rails.application.credentials.send(name) ||
super
end

def self.respond_to_missing?(*)
true
end
end

# Initialize the Rails application.
Rails.application.initialize!

Expand Down
7 changes: 3 additions & 4 deletions config/environments/production.rb
Expand Up @@ -14,10 +14,9 @@
config.consider_all_requests_local = false
config.action_controller.perform_caching = true

# Attempt to read encrypted secrets from `config/secrets.yml.enc`.
# Requires an encryption key in `ENV["RAILS_MASTER_KEY"]` or
# `config/secrets.yml.key`.
config.read_encrypted_secrets = true
# ENV["RAILS_MASTER_KEY"] or config/master.key is used to
# decrypt `config/credentials.yml.enc`.
config.require_master_key = true

# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
Expand Down
34 changes: 2 additions & 32 deletions config/secrets.yml
@@ -1,32 +1,2 @@
# Be sure to restart your server when you modify this file.

# Your secret key is used for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!

# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
# You can use `rails secret` to generate a secure secret key.

# Make sure the secrets in this file are kept private
# if you're sharing your code publicly.

# Shared secrets are available across all environments.

# shared:
# api_key: a1B2c3D4e5F6

# Environmental secrets are only available for that specific environment.

development:
secret_key_base: cbb78dd13c270bbbd6c89ff53db9fc84415f1de1140807ba85533681e4eca07bac26ad13261424727153a55b1b866a391c1f6a37514b4f88e5151b413c475185

test:
secret_key_base: 59aca2974ed5895fecbe65040b73dc38cde25af858e2be1fd6a2641302f174af5e674723d11150d6c63ebdedcb9e2c0cfcf6087f6d1ac2abc2e8dd282deba3f3

# Do not keep production secrets in the unencrypted secrets file.
# Instead, either read values from the environment.
# Or, use `bin/rails secrets:setup` to configure encrypted secrets
# and move the `production:` environment over there.

production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
# secret_key_base are automagically created for development and test envs,
# while the one for production should be defined in config/credentials.yml.enc

0 comments on commit 3886827

Please sign in to comment.