bastille 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ """