bastille 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .rbenv-*
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ script: 'bundle exec cucumber'
3
+ rvm:
4
+ - 1.9.3
5
+ - ruby-head
6
+ - ree
7
+ - rbx-18mode
8
+ - rbx-19mode
9
+ matrix:
10
+ allow_failures:
11
+ - rvm: rbx-18mode
12
+ - rvm: rbx-19mode
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'system_timer', :platform => :ruby_18
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Ryan Moran
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,96 @@
1
+ # Bastille
2
+ Bastille is a fortress for your configuration. It is a way to store environment variables
3
+ that you can use in your application in a distributable and secure way. Bastille consists
4
+ of a few pieces, a server, a command-line client, and a Ruby API that give you the ability
5
+ to store and retrieve these environment variables in a simple fashion. Since Bastille encrypts
6
+ all of your configuration on the client-side, the server is a simple KV store backed up by Redis.
7
+ The server has no way of decrypting your keys, so they will remain secure should the server ever
8
+ be compromised.
9
+
10
+ ## Installation
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'bastille'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install bastille
22
+
23
+ ## CLI Usage
24
+ Here is what you can do with bastille:
25
+
26
+ $ bastille token new
27
+ This action will require you to authenticate with Github. Are you sure you want to generate a new token? yes
28
+ Github username: ryanmoran
29
+ Password:
30
+ Where is the bastille server?: http://localhost:9000
31
+ What should we call this bastille token? This can be anything: bastille
32
+ Your token has been generated and authorized with github. It is stored in ~/.bastille. <3
33
+
34
+ $ bastille token show
35
+ username : ryanmoran
36
+ token : abc123
37
+ domain : http://localhost:9000
38
+ name : bastille
39
+ key : sekret
40
+
41
+ $ bastille token validate
42
+ Validating your token with the bastille server...
43
+ Your token is valid. \m/
44
+
45
+ $ bastille vault list
46
+ ryanmoran:
47
+ optimis:
48
+
49
+ $ bastille vault set ryanmoran:bastille KEY=value
50
+ "KEY => value" has been added to the ryanmoran:bastille vault.
51
+
52
+ $ bastille vault list
53
+ ryanmoran:
54
+ bastille
55
+ optimis:
56
+
57
+ $ bastille vault get ryanmoran:bastille
58
+ KEY=value
59
+
60
+ $ bastille vault set ryanmoran:bastille RAILS_ENV=production
61
+ "RAILS_ENV => production" has been added to the ryanmoran:bastille vault.
62
+
63
+ $ bastille vault get ryanmoran:bastille
64
+ KEY=value
65
+ RAILS_ENV=production
66
+
67
+ $ bastille vault delete ryanmoran:bastille KEY
68
+ Are you sure you want to remove the KEY key from the ryanmoran:bastille vault? yes
69
+ OK!
70
+
71
+ $ bastille vault get ryanmoran:bastille
72
+ RAILS_ENV=production
73
+
74
+ $ bastille vault delete ryanmoran:bastille
75
+ Are you sure you want to delete the ryanmoran:bastille vault? yes
76
+ OK!
77
+
78
+ $ bastille vault list
79
+ ryanmoran:
80
+ optimis:
81
+
82
+ ## Server
83
+ Hosting bastille is very simple. Here is an example `config.ru`.
84
+
85
+ require 'rubygems'
86
+ require 'bastille/server'
87
+
88
+ run Bastille::Server
89
+
90
+ ## Contributing
91
+
92
+ 1. Fork it
93
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
94
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
95
+ 4. Push to the branch (`git push origin my-new-feature`)
96
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bastille.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bastille/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'bastille'
8
+ gem.version = Bastille::VERSION
9
+ gem.authors = ['Ryan Moran']
10
+ gem.email = ['ryan.moran@gmail.com']
11
+ gem.description = %q{KV Storage As a Service, LOLz}
12
+ gem.summary = %q{KV Storage As a Service, LOLz}
13
+ gem.homepage = 'https://github.com/ryanmoran/bastille'
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_dependency 'gibberish'
21
+ gem.add_dependency 'highline'
22
+ gem.add_dependency 'httparty'
23
+ gem.add_dependency 'multi_json'
24
+ gem.add_dependency 'octokit'
25
+ gem.add_dependency 'redis'
26
+ gem.add_dependency 'redis-namespace'
27
+ gem.add_dependency 'sinatra'
28
+ gem.add_dependency 'thor'
29
+
30
+ gem.add_development_dependency 'aruba'
31
+ gem.add_development_dependency 'mimic'
32
+ gem.add_development_dependency 'fakeredis'
33
+ end
data/bin/bastille ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # vim:set ft=ruby:
3
+
4
+ require 'rubygems'
5
+ require 'bastille/cli'
6
+
7
+ Bastille::CLI::Executable.start
data/config.ru ADDED
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'bastille/server'
3
+
4
+ run Bastille::Server
@@ -0,0 +1,15 @@
1
+ Feature: Run `bastille`
2
+ In order to view the commands available for this application
3
+ As a user
4
+ I want to have the `bastille` command print a lising of the subcommands it supports
5
+
6
+ Scenario: list all subcommands
7
+ When I run `bastille`
8
+ Then the output should contain:
9
+ """
10
+ Tasks:
11
+ bastille help [TASK] # Describe available tasks or one specific task
12
+ bastille token [TASK] # Provides the user with tools to create and view th...
13
+ bastille vault [TASK] # Provides access to your vaults
14
+ """
15
+
@@ -0,0 +1,7 @@
1
+ require 'aruba/cucumber'
2
+
3
+ Aruba.configure do |config|
4
+ config.before_cmd do |cmd|
5
+ set_env 'BASTILLE_STORE', '.bastille'
6
+ end
7
+ end
@@ -0,0 +1,69 @@
1
+ require 'mimic'
2
+
3
+ OCTOKIT_DOMAIN = 'http://localhost:9999'
4
+
5
+ Aruba.configure do |config|
6
+ config.before_cmd do |cmd|
7
+ set_env 'OCTOKIT_API_ENDPOINT', OCTOKIT_DOMAIN
8
+ set_env 'OCTOKIT_WEB_ENDPOINT', OCTOKIT_DOMAIN
9
+ end
10
+ end
11
+
12
+ Mimic.mimic :port => 9999 do
13
+ set :rate_limit, 5000
14
+ set :raise_errors, Proc.new { false }
15
+ set :show_exceptions, false
16
+
17
+ before do
18
+ headers 'X-RateLimit-Limit' => settings.rate_limit.to_s,
19
+ 'X-RateLimit-Remaining' => (settings.rate_limit - 1).to_s,
20
+ 'Content-Type' => 'application/json'
21
+ end
22
+
23
+ after do
24
+ settings.rate_limit = settings.rate_limit - 1
25
+ end
26
+
27
+ post '/authorizations' do
28
+ headers 'Location' => "#{OCTOKIT_DOMAIN}/authorizations/1"
29
+ body = {
30
+ 'id' => 1,
31
+ 'url' => "#{OCTOKIT_DOMAIN}/authorizations/1",
32
+ 'scopes' => [
33
+ 'public_repo'
34
+ ],
35
+ 'token' => 'abc123',
36
+ 'app' => {
37
+ 'url' => 'http://my-github-app.com',
38
+ 'name' => 'my github app'
39
+ },
40
+ 'note' => 'optional note',
41
+ 'note_url' => 'http://optional/note/url',
42
+ 'updated_at' => '2011-09-06T20:39:23Z',
43
+ 'created_at' => '2011-09-06T17:26:27Z'
44
+ }.to_json
45
+ [201, headers, body]
46
+ end
47
+
48
+ get '/rate_limit' do
49
+ json = {
50
+ 'rate' => {
51
+ 'remaining' => (settings.rate_limit - 1),
52
+ 'limit' => settings.rate_limit
53
+ }
54
+ }.to_json
55
+ [200, headers, json]
56
+ end
57
+
58
+ get '/user/orgs' do
59
+ json =[
60
+ {
61
+ 'login' => 'something',
62
+ 'id' => 2,
63
+ "url" => "#{OCTOKIT_DOMAIN}/orgs/something"
64
+ }
65
+ ].to_json
66
+ [200, headers, json]
67
+ end
68
+
69
+ end
@@ -0,0 +1,55 @@
1
+ require 'bastille/server'
2
+ require 'fakeredis'
3
+
4
+ module TestServer
5
+ extend self
6
+
7
+ HOST = '127.0.0.1'
8
+ PORT = 9000
9
+ SERVER = 'webrick'
10
+
11
+ def run!
12
+ @thread = Thread.fork do
13
+ ENV['RACK_ENV'] = 'test'
14
+ Rack::Server.start :app => Bastille::Server.new,
15
+ :Host => HOST,
16
+ :Port => PORT,
17
+ :server => SERVER,
18
+ :Logger => WEBrick::Log::new("/dev/null", 7),
19
+ :AccessLog => []
20
+ end
21
+ wait_for_service
22
+ end
23
+
24
+ def stop!
25
+ @thread.kill
26
+ end
27
+
28
+ def listening?
29
+ begin
30
+ socket = TCPSocket.new(HOST, PORT)
31
+ socket.close unless socket.nil?
32
+ true
33
+ rescue Errno::ECONNREFUSED, SocketError
34
+ false
35
+ end
36
+ end
37
+
38
+ def wait_for_service(timeout = 5)
39
+ start_time = Time.now
40
+
41
+ until listening?
42
+ if timeout && (Time.now > (start_time + timeout))
43
+ raise SocketError.new("Socket did not open within #{timeout} seconds")
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ at_exit do
50
+ TestServer.stop!
51
+ end
52
+
53
+ Octokit.api_endpoint = OCTOKIT_DOMAIN
54
+ Octokit.web_endpoint = OCTOKIT_DOMAIN
55
+ TestServer.run!
@@ -0,0 +1,71 @@
1
+ Feature: Run `bastille token`
2
+ In order to generate a valid token set for authenticating with the bastille server
3
+ As a user
4
+ I want to have the `bastille tokenize` command prompt me to authenticate with Github
5
+ And then serialize this the resulting OAuth token and data from Github
6
+ And store that data in a file at ~/.bastille
7
+
8
+ Scenario: list token subcommands
9
+ When I run `bastille token`
10
+ Then the output should contain:
11
+ """
12
+ Tasks:
13
+ bastille token delete # Deletes the token
14
+ bastille token help [COMMAND] # Describe subcommands or one specific subco...
15
+ bastille token new # Generates an OAuth token from github to au...
16
+ bastille token show # Prints your credentials out to the command...
17
+ bastille token validate # Validates your token with the bastille ser...
18
+ """
19
+
20
+ Scenario: run `token new`, `token validate`, and `token delete`
21
+ When I run `bastille token new` interactively
22
+ And I wait for output to contain "Are you sure you want to generate a new token?"
23
+ And I type "yes"
24
+ And I wait for output to contain "Github username:"
25
+ And I type "mister.happy"
26
+ And I wait for output to contain "Password:"
27
+ And I type "sekret"
28
+ And I wait for output to contain "Where is the bastille server?"
29
+ And I type "http://localhost:9000"
30
+ And I wait for output to contain "What should we call this bastille token?"
31
+ And I type "banana"
32
+ Then the output should not contain "The username and password entered do not match."
33
+ And the exit status should be 0
34
+ And a file named ".bastille" should exist
35
+ When I run `bastille token validate`
36
+ Then the output should contain:
37
+ """
38
+ Validating your token with the bastille server...
39
+ Your token is valid. \m/
40
+ """
41
+ When I run `bastille token delete` interactively
42
+ And I wait for output to contain "Are you sure you want to delete your token? This cannot be undone."
43
+ And I type "yes"
44
+ Then a file named ".bastille" should not exist
45
+
46
+ Scenario: run `token show`
47
+ Given a file named ".bastille" with:
48
+ """
49
+ ---
50
+ :username: mister.happy
51
+ :token: abc123
52
+ :domain: http://localhost:9000
53
+ :name: banana
54
+ """
55
+ When I run `bastille token show`
56
+ Then the output should contain:
57
+ """
58
+ domain : http://localhost:9000
59
+ name : banana
60
+ token : abc123
61
+ username : mister.happy
62
+ """
63
+ Then the exit status should be 0
64
+
65
+ Scenario: decide not to generate new token
66
+ When I run `bastille token new` interactively
67
+ And I wait for output to contain "Are you sure you want to generate a new token?"
68
+ And I type "no"
69
+ Then the output should not contain "Github username"
70
+ And the exit status should be 0
71
+
@@ -0,0 +1,79 @@
1
+ Feature: Run `bastille tokenize`
2
+ In order to generate a valid token set for authenticating with the bastille server
3
+ As a user
4
+ I want to have the `bastille tokenize` command prompt me to authenticate with Github
5
+ And then serialize this the resulting OAuth token and data from Github
6
+ And store that data in a file at ~/.bastille
7
+
8
+ Background:
9
+ Given a file named ".bastille" with:
10
+ """
11
+ ---
12
+ :username: mister.happy
13
+ :token: abc123
14
+ :domain: http://localhost:9000
15
+ :name: banana
16
+ """
17
+
18
+ Scenario: list subcommands
19
+ When I run `bastille vault`
20
+ Then the output should contain:
21
+ """
22
+ Tasks:
23
+ bastille vault delete [SPACE]:[VAULT] (KEY) # Deletes the given vault...
24
+ bastille vault get [SPACE]:[VAULT] # Retrieves the contents ...
25
+ bastille vault help [COMMAND] # Describe subcommands or...
26
+ bastille vault list # List out existing vaults
27
+ bastille vault set [SPACE]:[VAULT] [KEY]=[VALUE] # Sets a key in the given...
28
+ """
29
+
30
+ Scenario: list existing vaults
31
+ When I run `bastille vault list`
32
+ Then the output should contain:
33
+ """
34
+ mister.happy:
35
+ something:
36
+ """
37
+
38
+ Scenario: set and get a key from a vault, list vaults, delete vault
39
+ When I run `bastille vault set mister.happy:test RAILS_ENV=production`
40
+ Then the output should contain:
41
+ """
42
+ "RAILS_ENV => production" has been added to the mister.happy:test vault.
43
+ """
44
+ When I run `bastille vault get mister.happy:test`
45
+ Then the output should contain:
46
+ """
47
+ RAILS_ENV=production
48
+ """
49
+ When I run `bastille vault list`
50
+ Then the output should contain:
51
+ """
52
+ mister.happy:
53
+ test
54
+ something:
55
+ """
56
+ When I run `bastille vault delete mister.happy:test` interactively
57
+ And I wait for output to contain "Are you sure you want to delete the mister.happy:test vault?"
58
+ And I type "yes"
59
+ Then the output should contain "OK!"
60
+ When I run `bastille vault list`
61
+ Then the output should contain:
62
+ """
63
+ mister.happy:
64
+ something:
65
+ """
66
+
67
+ Scenario: try to get a vault you don't own
68
+ When I run `bastille vault get defunkt:resque`
69
+ Then the output should contain:
70
+ """
71
+ Github is saying that you are not the owner of this space. Your spaces are ["mister.happy", "something"]
72
+ """
73
+
74
+ Scenario: try to set a key you don't own
75
+ When I run `bastille vault set defunkt:resque BANANA=yummy`
76
+ Then the output should contain:
77
+ """
78
+ Github is saying that you are not the owner of this space. Your spaces are ["mister.happy", "something"]
79
+ """