secretive 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in secretive.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Reade Harris
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # Secretive
2
+ ### Secrets, secrets, are now fun. *(Exposed secrets hurt someone.)*
3
+
4
+ Secretive is a way to configure your application's ENV variables using a .yml file.
5
+
6
+ It includes Rails integration, including a generator and a task for sharing secrets with Heroku.
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'secretive'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install secretive
21
+
22
+ ## Usage
23
+
24
+ ### Setting Up (With Rails)
25
+
26
+ Simply run `rails g secrets` to create and automatically .gitignore the required .yml files.
27
+
28
+ When starting your Rails application, top-level variables and any variables in a group with the same name as your Rails environment will become ENV variables.
29
+
30
+ For example, take following YAML file:
31
+
32
+ TOP_SECRET: "This will self-destruct."
33
+
34
+ development:
35
+ SUPER_SECRET: "Jeremiah was a bullfrog."`
36
+ production:
37
+ SUPER_SECRET: "He was a good friend of mine."
38
+
39
+ In development:
40
+
41
+ $ rails console -e development
42
+ > ENV["SUPER_SECRET"]
43
+ => "Jeremiah was a bullfrog."
44
+
45
+ > ENV["TOP_SECRET"]
46
+ => "This will self-destruct."
47
+
48
+ In production:
49
+
50
+ $ rails console -e production
51
+ > ENV["SUPER_SECRET"]
52
+ => "He was a good friend of mine."
53
+
54
+ > ENV["TOP_SECRET"]
55
+ => "This will self-destruct."
56
+
57
+ ### Setting Up (Without Rails)
58
+
59
+ If not using Rails, create a `config/secrets.yml` file (or whatever you want to call it) and call `Secretive.environmentalize!` somewhere in your application.
60
+
61
+ ### Customizing
62
+
63
+ You can choose which file to use as your secrets file by setting `Secretive.file = "../path/to/myfile"` before calling `Secretive.environmentalize!`.
64
+
65
+ You can also pass `Secretive.environmentalize!` a scope. Top-level variables will always be loaded.
66
+
67
+ For example, take following YAML file:
68
+
69
+ TOP_SECRET: "This will self-destruct."
70
+
71
+ superheroes:
72
+ BEST_HERO: "Harvey Birdman"`
73
+ supervillains:
74
+ BEST_VILLAIN: "Mentok, Mind-Taker"
75
+
76
+ After calling `Secretive.environmentalize!("superheroes")`:
77
+
78
+ $ irb
79
+ > ENV["BEST_HERO"]
80
+ => "Harvey Birdman"
81
+
82
+ > ENV["TOP_SECRET"]
83
+ => "This will self-destruct."
84
+
85
+ > ENV["BEST_VILLAIN"]
86
+ => nil
87
+
88
+ ## Sharing with Heroku
89
+
90
+ Secretive comes with a rake task for sharing secrets with Heroku.
91
+
92
+ Run `rake secretive:share_with[yourapp]` to convert all values in the `production` scope of your .yml file into ENV variables in the Heroku app.
93
+
94
+ ## Contributing
95
+
96
+ 1. Fork it
97
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
98
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
99
+ 4. Push to the branch (`git push origin my-new-feature`)
100
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,18 @@
1
+ class SecretsGenerator < ::Rails::Generators::Base
2
+ def create_secrets_file
3
+ create_file("#{Rails.root}/config/secrets.yml")
4
+ end
5
+
6
+ def create_example_file
7
+ create_file("#{Rails.root}/config/secrets.yml.example")
8
+ end
9
+
10
+ def gitignore_secrets_file
11
+ append_to_file("#{Rails.root}/.gitignore") do
12
+ "\n\n" +
13
+ "# Sensitive API and password information.\n" +
14
+ "# Keep it secret. Keep it safe.\n" +
15
+ "config/secrets.yml"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,45 @@
1
+ module Secretive
2
+ class Loader
3
+ class << self
4
+ def environmentalize!(yaml_file, scope=nil)
5
+ unless File.exists?(yaml_file)
6
+ warn "secretive attempted to initialize, but #{yaml_file} does not exist."
7
+ return
8
+ end
9
+
10
+ vars = YAML.load(File.open(yaml_file))
11
+
12
+ convert_to_env_vars(vars)
13
+ convert_to_env_vars(vars.fetch(scope)) if scope.present?
14
+ end
15
+
16
+ def for_heroku(yaml_file, scope=nil)
17
+ vars = YAML.load(File.open(yaml_file))
18
+
19
+ heroku_string = convert_vars_to_string(vars)
20
+ heroku_string += convert_vars_to_string(vars.fetch(scope)) if scope.present?
21
+ heroku_string
22
+ end
23
+
24
+ private
25
+
26
+ def convert_to_env_vars(vars)
27
+ return unless vars.present?
28
+
29
+ vars.each do |key, value|
30
+ ENV[key] = value unless value.respond_to?(:each) || value.nil?
31
+ end
32
+ end
33
+
34
+ def convert_vars_to_string(vars)
35
+ return unless vars.present?
36
+
37
+ string = ""
38
+ vars.each do |key, value|
39
+ string.concat("#{key}=#{value} ") unless value.respond_to?(:each) || value.nil?
40
+ end
41
+ string
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,15 @@
1
+ module Secretive
2
+ class Railtie < ::Rails::Railtie
3
+ config.before_initialize do
4
+ Secretive.environmentalize!(Rails.env) unless Rails.env.production?
5
+ end
6
+
7
+ rake_tasks do
8
+ load File.expand_path('../../tasks/share.rake', __FILE__)
9
+ end
10
+
11
+ generators do
12
+ require File.expand_path('../../generators/secrets_generator', __FILE__)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module Secretive
2
+ VERSION = "0.0.7"
3
+ end
data/lib/secretive.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'active_support/all'
2
+ require 'secretive/version'
3
+ require 'secretive/loader'
4
+ require 'secretive/railtie' if defined?(Rails)
5
+
6
+ module Secretive
7
+ class << self
8
+ def file
9
+ @@file ||= 'config/secrets.yml'
10
+ end
11
+
12
+ def file=(file)
13
+ @@file = file
14
+ end
15
+
16
+ def configure
17
+ yield self
18
+ end
19
+
20
+ def environmentalize!(scope=nil)
21
+ Loader.environmentalize!(self.file, scope)
22
+ end
23
+
24
+ def for_heroku(scope=nil)
25
+ Loader.for_heroku(self.file, scope)
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,21 @@
1
+ require 'heroku'
2
+
3
+ namespace :secretive do
4
+ desc 'Set environment vars defined in the production group of config/secrets.yml on the specified Heroku app.'
5
+ task :share_with, :heroku_app do |task, args|
6
+ raise "This task requires the heroku gem and it could not be found." unless defined?(Heroku)
7
+ raise "Which heroku app do you want to share secrets with? Format is rake secretive:share[heroku_app]" unless args[:heroku_app].present?
8
+
9
+ @heroku_app = args[:heroku_app]
10
+
11
+ msg = "This task will sync ALL ENVIRONMENT VARIABLES in the `#{@heroku_app}` app "
12
+ msg += "with the values defined in the `production` group of config/secrets.yml. "
13
+ msg += "Are you sure you want to proceed? (y/n)"
14
+ puts msg
15
+
16
+ confirmation = $stdin.gets.chomp
17
+ raise unless confirmation == "y"
18
+
19
+ sh "heroku config:add #{Secrets.for_heroku('production')} --app #{@heroku_app}"
20
+ end
21
+ end
data/secretive.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/secretive/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Singlebrook Technology"]
6
+ gem.email = ["info@singlebrook.com"]
7
+ gem.description = %q{Secretive converts variables in a YAML file into ENV vars. It's useful for storing API keys and other sensitive information.}
8
+ gem.summary = %q{Convert variables in a YAML file into ENV vars.}
9
+
10
+ gem.files = `git ls-files`.split($\)
11
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
12
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
13
+ gem.name = "secretive"
14
+ gem.require_paths = ["lib"]
15
+ gem.version = Secretive::VERSION
16
+
17
+ gem.add_dependency 'activesupport', '~> 3.2.0'
18
+ gem.add_dependency 'heroku', '~> 2.0'
19
+ gem.add_development_dependency 'rspec', '~> 2.9.0'
20
+ end
File without changes
@@ -0,0 +1,18 @@
1
+ FAVORITE_COLOR: "Rainbow"
2
+ MOST_AWESOME_NINJA_TURTLE: "Donatello"
3
+ EMPTY_VAR:
4
+
5
+ fools:
6
+ FIRST_FOOL: "Feste"
7
+ SECOND_FOOL: "Patchface"
8
+
9
+ heroes:
10
+ FIRST_HERO: "Lancelot"
11
+ SECOND_HERO: "Bilbo"
12
+
13
+ filled_with_empty:
14
+ EMPTY_VAR:
15
+ EMPTY_VAR:
16
+ EMPTY_VAR:
17
+
18
+ empty_scope:
@@ -0,0 +1,81 @@
1
+ require_relative '../lib/secretive/loader'
2
+
3
+ describe Secretive::Loader do
4
+ subject { Secretive::Loader }
5
+
6
+ let(:test_secrets) { File.expand_path("../fixtures/test_secrets.yml", __FILE__) }
7
+ let(:empty_secrets) { File.expand_path("../fixtures/empty_secrets.yml", __FILE__) }
8
+ let(:nonexistent_secrets) { File.expand_path("../fixtures/nonexistent_secrets.yml", __FILE__) }
9
+
10
+ describe "environmentalizing" do
11
+ it "environmentalizes all top-level variables" do
12
+ subject.environmentalize!(test_secrets)
13
+
14
+ ENV["FAVORITE_COLOR"].should == "Rainbow"
15
+ ENV["MOST_AWESOME_NINJA_TURTLE"].should == "Donatello"
16
+ end
17
+
18
+ it "doesn't barf when given an empty variable" do
19
+ expect { subject.environmentalize!(test_secrets) }.not_to raise_error
20
+ end
21
+
22
+ it "doesn't barf when given an empty file" do
23
+ expect { subject.environmentalize!(empty_secrets) }.not_to raise_error
24
+ end
25
+
26
+ context "without a secrets file" do
27
+ it "doesn't barf" do
28
+ expect { subject.environmentalize!(nonexistent_secrets) }.not_to raise_error
29
+ end
30
+
31
+ it "gives a warning" do
32
+ subject.should_receive(:warn).with("secretive attempted to initialize, but #{nonexistent_secrets} does not exist.")
33
+ subject.environmentalize!(nonexistent_secrets)
34
+ end
35
+ end
36
+
37
+ context "when given a scope" do
38
+ it "environmentalizes variables in the scope" do
39
+ subject.environmentalize!(test_secrets, "fools")
40
+
41
+ ENV["FIRST_FOOL"].should == "Feste"
42
+ ENV["SECOND_FOOL"].should == "Patchface"
43
+ end
44
+
45
+ it "doesn't barf when given a scope filled with empty variables" do
46
+ expect { subject.environmentalize!(test_secrets, "filled_with_empty") }.not_to raise_error
47
+ end
48
+
49
+ it "doesn't barf when given an empty scope" do
50
+ expect { subject.environmentalize!(test_secrets, "empty_scope") }.not_to raise_error
51
+ end
52
+
53
+ it "still environmentalizes top-level variables" do
54
+ ENV["FAVORITE_COLOR"] = nil
55
+
56
+ subject.environmentalize!(test_secrets, "fools")
57
+ ENV["FAVORITE_COLOR"].should be_present
58
+ end
59
+
60
+ it "does not environmentalize other scopes" do
61
+ ENV["FIRST_FOOL"] = nil
62
+
63
+ subject.environmentalize!(test_secrets, "heroes")
64
+ ENV["FIRST_FOOL"].should_not be_present
65
+ end
66
+ end
67
+
68
+ end
69
+
70
+ describe "Heroku string:" do
71
+ it "can return a string suitable for adding vars to Heroku" do
72
+ heroku_string = subject.for_heroku(test_secrets, "fools")
73
+ heroku_string.should == "FAVORITE_COLOR=Rainbow MOST_AWESOME_NINJA_TURTLE=Donatello FIRST_FOOL=Feste SECOND_FOOL=Patchface "
74
+ end
75
+
76
+ it "does not include empty scopes in the string" do
77
+ heroku_string = subject.for_heroku(test_secrets, "fools")
78
+ heroku_string.should_not include "empty_scope"
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,22 @@
1
+ require_relative '../lib/secretive'
2
+
3
+ describe Secretive do
4
+ subject { Secretive }
5
+
6
+ it "supports reading and writing a file" do
7
+ subject.file = "myfile"
8
+ subject.file.should == "myfile"
9
+ end
10
+
11
+ it "can be configured using a block" do
12
+ subject.should_receive(:file=).with("stuff")
13
+ subject.configure do |config|
14
+ config.file = "stuff"
15
+ end
16
+ end
17
+
18
+ it "delegates #environmentalize! to the Loader" do
19
+ subject::Loader.should_receive(:environmentalize!)
20
+ subject.environmentalize!
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: secretive
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.7
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Singlebrook Technology
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 3.2.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 3.2.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: heroku
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '2.0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '2.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 2.9.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.9.0
62
+ description: Secretive converts variables in a YAML file into ENV vars. It's useful
63
+ for storing API keys and other sensitive information.
64
+ email:
65
+ - info@singlebrook.com
66
+ executables: []
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - .gitignore
71
+ - .rspec
72
+ - Gemfile
73
+ - LICENSE
74
+ - README.md
75
+ - Rakefile
76
+ - lib/generators/secrets_generator.rb
77
+ - lib/secretive.rb
78
+ - lib/secretive/loader.rb
79
+ - lib/secretive/railtie.rb
80
+ - lib/secretive/version.rb
81
+ - lib/tasks/share.rake
82
+ - secretive.gemspec
83
+ - spec/fixtures/empty_secrets.yml
84
+ - spec/fixtures/test_secrets.yml
85
+ - spec/loader_spec.rb
86
+ - spec/secrets_spec.rb
87
+ homepage:
88
+ licenses: []
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 1.8.23
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Convert variables in a YAML file into ENV vars.
111
+ test_files:
112
+ - spec/fixtures/empty_secrets.yml
113
+ - spec/fixtures/test_secrets.yml
114
+ - spec/loader_spec.rb
115
+ - spec/secrets_spec.rb
116
+ has_rdoc: