nimbussecure 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ binstubs
5
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in nimbussecure.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # Nimbus Secure Store Client
2
+ This gem provides the functionality required to talk to the Nimbus Secure
3
+ service.
4
+ Nimbus Secure is a service that provides highly encrypted storage of
5
+ keys, passwords, tokens, and other private information necessary for running
6
+ an application.
7
+ For instance, you may store database credentials, service credentials,
8
+ session cookie encryption keys, AWS keys, and other sensitive information
9
+ without fear of them being stolen or accessible from any unauthorized
10
+ individual.
11
+ The data is stored encrypted, and the encryption keys are not communicated
12
+ to the Nimbus Secure, meaning no one other than you may have access
13
+ to this secure information.
14
+
15
+ # The Service
16
+ To use this Gem, you must sign up for the service by visiting
17
+ www.nimbus secure.com and signing up for an account. Both
18
+ paid and free accounts are available.
19
+
20
+ Once you sign up for the service, you create crypt keys, which are
21
+ secured tokens used to encrypt and decrypt the data you store within
22
+ the service. While you set up the crypt keys from the service
23
+ website, the crypt keys themselves are never sent to our servers,
24
+ only you and anyone or system you authorize by giving them your
25
+ crypt key will have access to the stored data within the service.
26
+
27
+ You may create as many crypt keys as you desire. Typically, one per
28
+ service or system is a good choice. Additionally, you can add new
29
+ crypt keys and roll your data over to use a new crypt key very
30
+ easily in order to increase your security (key rotation). Each crypt
31
+ key has a name for easy identification, and we store a salted digest
32
+ of the key itself to verify correctness when it is provided.
33
+
34
+ Once your crypt keys are setup, you then enter all your sensitive data
35
+ as "stored keys". Stored keys are encrypted using your specified
36
+ crypt_keys before they are uploaded to our servers.
37
+
38
+ For security purposes, anytime the website or this Gem require a
39
+ crypt key, it must be provided by you (the user of the website or Gem),
40
+ and the value provided is checked against a stored signed digest
41
+ for valdity before it is used to perform the requested encryption/decryption.
42
+ The requested encryption/decryption occurs entirely within the client's
43
+ computer (user's browser for the website, application server for users
44
+ of the Gem), and is never communicated with Nimbus Secure directly.
45
+
46
+ # Using the Secured Data
47
+ Once you have your data uploaded to your service, you can then
48
+ install this Gem into your application, and use it's programmatic
49
+ interface (or command line) to download and decrypt the stored
50
+ credential so you may use it within your application.
51
+
52
+ # Needed Credentials
53
+ In order to use this Gem, you need two pieces of secure information.
54
+ The first is an API key that provides access to the API and allows
55
+ you to access your online account. You can create an API key by
56
+ logging into the service.
57
+
58
+ The second is the crypt key that you created above that is used
59
+ to encrypt/decrypt your stored data. If you used more than one key,
60
+ then you will need all the encrypted keys.
61
+
62
+ Typically, you store these two pieces of information outside of your
63
+ application source repository itself, and only provide them to your
64
+ application during application startup (typically via ENVIRONMENT
65
+ variables or other boot parameters). That way, you do not have
66
+ to share the credentials or persist them source repository.
67
+
68
+ Given these two pieces of information, this Gem, and the properly
69
+ setup service, you can dynamically grab all your sensitive credentials
70
+ and data needed to run your application. This typically happens during
71
+ your application boot up process.
72
+
73
+ # Setting up your .nibmussecure.yml file:
74
+ The easiest way to setup Nimbus Secure is to setup a configuration file in your home directory.
75
+ This file will contain sensitive information, so it should be marked as readable to you only
76
+ (permission mode 400). The following is a sample configuration file:
77
+
78
+ account: <my_account_id>
79
+ apikey: <my_accounts_apikey>
80
+ crypt_keys:
81
+ key1: <my_secret_value_for_key1>
82
+ key2: <my_secret_value_for_key2>
83
+
84
+ The value "<my_account_id>" is the same value that appears in the base part of your URL you use to
85
+ access Nmbus Secure. So, for example, if the URL you use to access Nimbus Secure is this:
86
+
87
+ https://www.nimbussecure.com/myaccount
88
+
89
+ Then your account id is "myaccount". Your "apikey" can be retrieved from the "Api Keys" tab in
90
+ Nimbus Secure.
91
+
92
+ For each encryption key you have in your account and you wish to use, you must have a line in the
93
+ "crypt_keys:"" section of the config file. In the above example, "key1" is the name assigned to the
94
+ first encryption key, and "<my_secret_value_for_key1>" is the secret value you assigned when
95
+ you created this encryption key.
96
+
97
+ # Using in Ruby
98
+ Assuming you have a stored key with a name "testmessage" setup, with an approprate encryption key.
99
+ Also assuming your ~/.nimbussecure.yml file is setup with your account identifier, API Key,
100
+ and the encryption key value. Then the following can be used to retrieve and decrypt a stored key:
101
+
102
+ require 'nimbussecure'
103
+ stored_value=nimbussecure.lookup_value "testmessage"
104
+ puts "The decrypted stored value is: #{stored_value}"
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ desc "Run all tests"
4
+ task :test do
5
+ require "#{File.dirname(Pathname.new(File.expand_path(__FILE__)).realpath.to_s).to_s}/test/run_tests.rb"
6
+ end
data/bin/nimbussecure ADDED
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env ruby
2
+ require 'yaml'
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+ require 'nimbussecure'
6
+
7
+ def keystore
8
+ $keystore||=NimbusSecure.new config_file: $filename
9
+ end
10
+
11
+ def usage
12
+ puts "
13
+ Usage:
14
+ nimbussecure [-f <config_file>] account
15
+ nimbussecure [-f <config_file>] lookup <name>
16
+ <value> is sent to stdout
17
+ Where:
18
+ -f <config_file> Specifies a config file (rather than \"~/.nimbussecure.yml\")
19
+ <value> is the specific value being encrypted and stored.
20
+
21
+ Config File
22
+ The config file should look like the following:
23
+ ================
24
+ account: myacct
25
+ apikey: myapikey
26
+ crypt_keys:
27
+ key1: value1
28
+ key2: value2
29
+ ================
30
+
31
+ NOTE:
32
+ account:
33
+ The account value (\"myacct\" in the example above) can be found based on the
34
+ URL you use to access Nimbus Secure.
35
+ If your URL is:
36
+ https://www.nimbussecure.com/my_acct/
37
+ Then the \"account\" value in your config file should be \"my_acct\"
38
+ apikey:
39
+ You can find your API Key by clicking on \"API Keys\" when you are logged into
40
+ the Nimbus Secure website.
41
+ crypt_keys:
42
+ This is a set of key/value pairs. The key is the name as defined in your
43
+ Nimbus Secure \"Encryption Keys\" section, and the value is the secret value
44
+ you used when you created your encryption key.
45
+ "
46
+ exit 1
47
+ end
48
+ def show_error
49
+ puts "Error: #{keystore.last_error_message}"
50
+ keystore.last_error_details.each do |subject,error_list|
51
+ error_list.each do |error|
52
+ puts " #{subject} #{error}"
53
+ end
54
+ end if keystore.last_error_details
55
+ end
56
+
57
+ def main
58
+ usage if ARGV.size<1
59
+ idx=0
60
+ $filename="~/.nimbussecure.yml"
61
+ if ARGV[idx]=='-f'
62
+ usage if ARGV.size<=2
63
+ $filename=ARGV[idx+1]
64
+ idx+=2
65
+ end
66
+ case ARGV[idx]
67
+ when "account" then
68
+ usage if ARGV.size!=idx+1
69
+ account
70
+ when "lookup" then
71
+ usage if ARGV.size!=idx+2
72
+ lookup ARGV[idx+1]
73
+ else
74
+ usage
75
+ end
76
+ end
77
+
78
+ def account
79
+ begin
80
+ account=keystore.account
81
+ puts " Name: #{account.name}"
82
+ puts " # Crypt Keys: #{account.num_crypt_keys}"
83
+ puts " # Stored Keys: #{account.num_stored_keys}"
84
+ rescue => error
85
+ puts "Error: #{error}"
86
+ end
87
+ end
88
+
89
+ def lookup name
90
+ begin
91
+ res=keystore.lookup name
92
+ if res.nil?
93
+ show_error
94
+ return
95
+ end
96
+ puts res.decrypted_value
97
+ rescue => error
98
+ puts "Error: #{error}"
99
+ end
100
+ end
101
+
102
+ main
@@ -0,0 +1,72 @@
1
+ require "nimbussecure/version"
2
+ require "nimbussecure/errors"
3
+ require "nimbussecure/attr_accessor"
4
+ require "nimbussecure/config"
5
+ require "nimbussecure/base"
6
+ require "nimbussecure/connect"
7
+ require "nimbussecure/results"
8
+ require "nimbussecure/accounts"
9
+ require "nimbussecure/crypt_key"
10
+ require "nimbussecure/stored_key"
11
+
12
+
13
+
14
+ #
15
+ # Simplified Usage
16
+ # (assumes ~/.nimbussecure.yml is setup)
17
+ # ======================================
18
+ #
19
+ # Get account details:
20
+ # nimbussecure.account
21
+ #
22
+ # Lookup a stored value and return the decrypted version (assumes crypt key is in ~/.nimbussecure.yml):
23
+ # nimbussecure.lookup_value :storedvalue_identifier
24
+ #
25
+ # Full Usage
26
+ # ==========
27
+ #
28
+ # Setup access:
29
+ # * Assumes ~/.nimbussecure.yml is setup:
30
+ # ns=NimbusSecure.new
31
+ # * Assumes otherfile.yml is setup:
32
+ # ns=NimbusSecure.new config_file: "otherfile.yml"
33
+ # * Manual Configuration:
34
+ # ns=NimbusSecure account: "ident", apikey: "apikey", crypt_keys: {key1: "value1",key2: "value2"}
35
+ #
36
+ # Get account details
37
+ # account=ns.account
38
+ # account.name
39
+ # account.num_crypt_keys
40
+ # account.num_stored_keys
41
+ #
42
+ # Get details on all configured encryption keys:
43
+ # crypt_keys=ns.crypt_keys
44
+ #
45
+ # Get all stored values:
46
+ # stored_keys=ns.stored_keys
47
+ #
48
+ # Lookup a single stored value:
49
+ # stored_key=ns.lookup ident
50
+ #
51
+ # With the stored_key object:
52
+ # stored_key.ident
53
+ # stored_key.decrypted_value # Assuming secret value for corresponding crypt_key is available locally
54
+ # stored_key.encrypted_value
55
+ # stored_key.key_type
56
+ #
57
+ # Ruby on Rails Usage
58
+ # ===================
59
+ #
60
+ # Example usage in Rails to load the secret_token (config/initializers/secret_token.rb):
61
+ # require 'nimbussecure'
62
+ # secret_token=nimbussecure.lookup "secret_token"
63
+ # raise "Secret token missing" unless secret_token
64
+ # NimbusData::Application.config.secret_token = secret_token.decrypted_value
65
+ # Or, alternately:
66
+ # require 'nimbussecure'
67
+ # secret_token=nimbussecure.lookup_value "secret_token"
68
+ # raise "Secret token missing" unless secret_token
69
+ # NimbusData::Application.config.secret_token = secret_token
70
+ #
71
+ # Assumes config file in ~/.nimbussecure
72
+ #
@@ -0,0 +1,16 @@
1
+ class NimbusSecure
2
+ class Account<NimbusSecure::Base
3
+ nimbus_attr_accessor :name,:num_crypt_keys,:num_stored_keys
4
+ def initialize name,num_crypt_keys,num_stored_keys
5
+ @name=name
6
+ @num_crypt_keys=num_crypt_keys
7
+ @num_stored_keys=num_stored_keys
8
+ end
9
+ end
10
+ def account
11
+ return @account if @account
12
+ res=request_get "/account"
13
+ raise ServerError,"Invalid Account" unless res and res["account"]
14
+ @account=Account.new res["account"]["name"],res["account"]["num_crypt_keys"],res["account"]["num_stored_keys"]
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ module NimbusSecureAttrAccessor
2
+ def nimbus_attr_accessor *list
3
+ list.each do |attr|
4
+ define_method(attr) do
5
+ instance_variable_get("@#{attr}")
6
+ end
7
+
8
+ define_method("#{attr}=") do |val|
9
+ instance_variable_set("@#{attr}",val)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ class NimbusSecure
15
+ private
16
+ class Base
17
+ class<<self
18
+ include NimbusSecureAttrAccessor
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,44 @@
1
+ class NimbusSecure
2
+ #
3
+ # Possible ways to initialize:
4
+ #
5
+ # 1) Explicit:
6
+ # ns=NimbusSecure.new account: "ident",apikey: "xyzzy", crypt_keys:{"key1":"value1","key2":"value2"}
7
+ # 2) File:
8
+ # ns=NimbusSecure.new config_file: "./nsconfig.yml"
9
+ # nsconfig.yml:
10
+ # -------------
11
+ # account: ident
12
+ # apikey: xxx
13
+ # crypt_keys:
14
+ # key1: value1
15
+ # key2: value2
16
+ # 3) YAML string (not file):
17
+ # ns=NimbusSecure.new config: "account: ident\napikey: xxx\ncrypt_keys:\n key1: value1\n key2:value2\n"
18
+ # 4) Default:
19
+ # ns=NimbusSecure.new
20
+ # ...reads configuration from ~/nimbussecure.yml
21
+ #
22
+ def initialize opts={}
23
+ raise InvalidConfig unless opts.respond_to?(:size) and opts.respond_to?(:[])
24
+ opts[:config_file]=File.expand_path("~/.nimbussecure.yml") if opts.size==0
25
+ if opts[:config] || opts[:config_file]
26
+ raw_config_str=opts[:config]
27
+ raw_config_str = File.read(File.expand_path(opts[:config_file])) if opts[:config_file]
28
+ raise InvalidConfigFile unless raw_config_str
29
+ opts=YAML.load(raw_config_str)
30
+ raise InvalidConfigFile unless opts
31
+ end
32
+ opts=Hash[opts.map{ |k, v| [k.to_sym, v] }]
33
+ config.account="xxx"
34
+ config.endpoint=opts[:endpoint].to_s if opts[:endpoint]
35
+ config.account=opts[:account].to_s
36
+ config.apikey=opts[:apikey].to_s
37
+ config.crypt_keys=Hash[opts[:crypt_keys].map{ |k, v| [k.to_sym, v.to_s] }] if opts[:crypt_keys]
38
+ raise InvalidConfig,"Config is missing or incomplete" unless config.valid?
39
+ end
40
+
41
+ end
42
+ def nimbussecure
43
+ @nimbussecure||=NimbusSecure.new
44
+ end
@@ -0,0 +1,19 @@
1
+ require 'yaml'
2
+ class NimbusSecure
3
+ class Config
4
+ attr_accessor :endpoint,:account,:apikey,:crypt_keys
5
+ def initialize
6
+ @crypt_keys={}
7
+ @endpoint="https://www.nimbussecure.com"
8
+ end
9
+ def invalid?
10
+ endpoint.nil? || account.nil? || apikey.nil? || crypt_keys.size==0
11
+ end
12
+ def valid?
13
+ !invalid?
14
+ end
15
+ end
16
+ def config
17
+ @config||=Config.new
18
+ end
19
+ end
@@ -0,0 +1,60 @@
1
+ require 'json'
2
+ require 'faraday'
3
+ class NimbusSecure
4
+ private
5
+ def request_get path,data={}
6
+ response=request_connection.get do |req|
7
+ req.url "/#{config.account}/api/v1#{path}"
8
+ req.params data unless data.nil? or data.size==0
9
+ end
10
+ process_response response
11
+ end
12
+ def request_post path,data={}
13
+ response=request_connection.post do |req|
14
+ req.url "/#{config.account}/api/v1#{path}"
15
+ req.body=data
16
+ end
17
+ process_response response
18
+ end
19
+ def request_connection
20
+ raise MissingOrInvalidConfiguation if config.endpoint.nil? or config.apikey.nil?
21
+ @request_connection||=Faraday.new(url:config.endpoint) do |builder|
22
+ builder.request :url_encoded
23
+ # builder.response :logger
24
+ builder.use AuthenticationMiddleware,config.apikey
25
+ builder.adapter :net_http
26
+ end
27
+ end
28
+ def process_response response
29
+ raise ServerError,response if(response.status!=200)
30
+ @last_result=JSON.parse(response.body)
31
+ @last_status=@last_result["status"]
32
+ @last_error_message=nil
33
+ @last_error_details=nil
34
+ @last_error_message=@last_result["errormsg"] if @last_status!="success"
35
+ @last_error_details=@last_result["errordetails"] if @last_status!="success"
36
+ @last_result.delete "status"
37
+ @last_result.delete "errormsg"
38
+ @last_result.delete "errordetails"
39
+ return nil if @last_status!="success"
40
+ @last_result
41
+ end
42
+ class AuthenticationMiddleware < Faraday::Middleware
43
+ def initialize(app,apikey)
44
+ super(app)
45
+ @apikey=apikey
46
+ end
47
+ def call(env)
48
+ set_header env,'X-Nimbus-Component-Key',@apikey
49
+ set_header env,'X-Nimbus-Client-Version',NimbusSecure::VERSION
50
+ set_header env,'X-Nimbus-Client',"muskratsoftware/NimbusSecureClient"
51
+ set_header env,'X-Nimbus-Language',"ruby"
52
+ @app.call(env)
53
+ end
54
+ def set_header(env,header,value)
55
+ unless env[:request_headers][header]
56
+ env[:request_headers][header] = value
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,75 @@
1
+ require 'gibberish'
2
+ class NimbusSecure
3
+ #
4
+ #
5
+ # Crypt Key
6
+ #
7
+ #
8
+ class CryptKey<NimbusSecure::Base
9
+ nimbus_attr_accessor :id,:valid,:ident,:salt,:digest,:key_value
10
+ def initialize nss,ck
11
+ @valid=true
12
+ @id=ck["id"]
13
+ @ident=ck["ident"].to_sym
14
+ @salt=ck["salt"]
15
+ @digest=ck["digest"]
16
+ if nss.config.crypt_keys[@ident.to_sym]
17
+ @key_value=nss.config.crypt_keys[@ident.to_sym]
18
+ sha256=Digest::SHA256.new
19
+ sha256 << @salt+@key_value
20
+ digest=sha256.to_s
21
+ if digest!=@digest
22
+ @valid=false
23
+ @salt=nil
24
+ @digest=nil
25
+ @key_value=nil
26
+ @invalid_message="Local encryption key does not match stored digest on server"
27
+ end
28
+ end
29
+ end
30
+ def valid?
31
+ @valid
32
+ end
33
+ def has_key_value?
34
+ return false unless valid?
35
+ !@key_value.nil?
36
+ end
37
+
38
+ def encrypt data
39
+ cipher.enc(data)
40
+ end
41
+ def decrypt data
42
+ cipher.dec(data)
43
+ end
44
+ private ################################################################################
45
+ def cipher
46
+ raise InvalidEncryptionKey,@invalid_message if @invalid_message
47
+ raise InvalidEncryptionKey,"Encryption Key does not have value configured locally" unless self.has_key_value?
48
+ raise InvalidEncryptionKey,"Invalid encryption key" unless self.valid?
49
+ Gibberish::AES.new(@key_value)
50
+ end
51
+ end
52
+
53
+ #
54
+ #
55
+ # Access Crypt Keys
56
+ #
57
+ #
58
+ def crypt_keys
59
+ res=request_get "/crypt_keys"
60
+ @cached_crypt_keys=res["crypt_keys"].map{|key|NimbusSecure::CryptKey.new self,key}
61
+ end
62
+ def crypt_keys_from_cache
63
+ return @cached_crypt_keys if @cached_crypt_keys
64
+ crypt_keys
65
+ end
66
+ def clear_crypt_key_cache
67
+ @cached_crypt_keys=nil
68
+ end
69
+ def crypt_key ident
70
+ crypt_keys_from_cache.each do |ck|
71
+ return ck if ck.ident==ident.to_sym
72
+ end
73
+ return nil
74
+ end
75
+ end
@@ -0,0 +1,7 @@
1
+ class NimbusSecure
2
+ class InvalidConfigFile<Exception;end
3
+ class InvalidConfig<Exception;end
4
+ class MissingOrInvalidConfiguation<Exception;end
5
+ class ServerError<Exception;end
6
+ class InvalidEncryptionKey<Exception;end
7
+ end
@@ -0,0 +1,20 @@
1
+ class NimbusSecure
2
+ def last_result
3
+ @last_result
4
+ end
5
+ def last_status
6
+ @last_status
7
+ end
8
+ def success?
9
+ last_status=="success"
10
+ end
11
+ def failed?
12
+ last_status!="success"
13
+ end
14
+ def last_error_message
15
+ @last_error_message
16
+ end
17
+ def last_error_details
18
+ @last_error_details
19
+ end
20
+ end
@@ -0,0 +1,47 @@
1
+ require 'gibberish'
2
+ class NimbusSecure
3
+ #
4
+ #
5
+ # Stored Key
6
+ #
7
+ #
8
+ #
9
+ class StoredKey<NimbusSecure::Base
10
+ nimbus_attr_accessor :id,:ident,:encrypted_value,:decrypted_value,:crypt_key,:key_type
11
+ def initialize nss,skparams
12
+ @id=skparams["id"]
13
+ @ident=skparams["ident"]
14
+ @encrypted_value=skparams["encrypted_value"]
15
+ @decrypted_value=nil
16
+ @crypt_key=NimbusSecure::CryptKey.new(nss,skparams["crypt_key"])
17
+ @key_type=skparams["key_type"]
18
+ end
19
+ def apply_crypt_key ck
20
+ self.decrypted_value=ck.decrypt self.encrypted_value
21
+ end
22
+ def value
23
+ apply_crypt_key self.crypt_key unless decrypted_value
24
+ decrypted_value
25
+ end
26
+ end
27
+
28
+ def lookup ident #,crypt_key
29
+ res=request_get "/stored_keys/#{ident}/locate"
30
+ return nil unless res
31
+ return nil unless res["stored_key"]
32
+ stored_key=NimbusSecure::StoredKey.new self,res["stored_key"]
33
+ ck=stored_key.crypt_key
34
+ return nil unless stored_key.encrypted_value
35
+ stored_key.apply_crypt_key ck
36
+ stored_key
37
+ end
38
+ def lookup_value ident
39
+ sk=lookup ident
40
+ return nil if sk.nil?
41
+ sk.value
42
+ end
43
+ def stored_keys
44
+ res=request_get "/stored_keys"
45
+ res["stored_keys"].map{|key|NimbusSecure::StoredKey.new self,key}
46
+ end
47
+ end
@@ -0,0 +1,3 @@
1
+ class NimbusSecure
2
+ VERSION = "0.5.0"
3
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "nimbussecure/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "nimbussecure"
7
+ s.version = NimbusSecure::VERSION
8
+ s.authors = ["Lee Atchison"]
9
+ s.email = ["lee@nimbussecure.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Client library for NimbusSecure}
12
+ s.description = %q{Client library for NimbusSecure}
13
+
14
+ s.rubyforge_project = "nimbussecure"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "minitest"
22
+ s.add_development_dependency "vcr"
23
+ s.add_development_dependency "fakeweb"
24
+ s.add_runtime_dependency "faraday"
25
+ # s.add_runtime_dependency "rest-client"
26
+ s.add_runtime_dependency "gibberish"
27
+ end
data/pry_load.rb ADDED
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH << File.dirname(File.expand_path(__FILE__).to_s).to_s+"/lib/"
2
+ require 'nimbussecure'
@@ -0,0 +1,18 @@
1
+ require 'minitest_helper'
2
+
3
+ describe NimbusSecure::Account do
4
+ before do
5
+ @ns=NimbusSecure.new({endpoint: "http://localhost:3000",
6
+ account: "vcrtest",
7
+ apikey: "34807a2d4d-a9990c4748218eb6ed-70886bc0fd",
8
+ crypt_keys:{"primary"=>"xyzzyxyzzy"}})
9
+ end
10
+ it "should get a list of all accounts (when there is just one)" do
11
+ VCR.use_cassette "accounts/test" do
12
+ acct=@ns.account
13
+ acct.name.must_equal "VCR Account"
14
+ acct.num_crypt_keys.must_equal 23
15
+ acct.num_stored_keys.must_equal 34
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,31 @@
1
+ require 'minitest_helper'
2
+ describe "Key Lookup" do
3
+ before do
4
+ @ns=NimbusSecure.new({endpoint: "http://localhost:3000",
5
+ account: "vcrtest",
6
+ apikey: "34807a2d4d-a9990c4748218eb6ed-70886bc0fd",
7
+ crypt_keys:{"primary"=>"xyzzyxyzzy","secondary"=>"yzzyxyzzyx"}})
8
+ end
9
+ it "should be able to lookup a key and decrypt it" do
10
+ VCR.use_cassette "lookup/key1" do
11
+ @ns.lookup_value(:test1).must_equal "This is a test stored key"
12
+ end
13
+ end
14
+ it "should be able to lookup a second key and decrypt it" do
15
+ VCR.use_cassette "lookup/key2" do
16
+ code=@ns.lookup_value(:test1).must_equal "This is a test stored key"
17
+ code=@ns.lookup_value(:test2).must_equal "This is another test stored key"
18
+ end
19
+ end
20
+ it "should be able to fail gracefully if key is not found" do
21
+ VCR.use_cassette "lookup/key3" do
22
+ code=@ns.lookup_value :invalidkey
23
+ code.must_be_nil
24
+ @ns.success?.must_equal false
25
+ @ns.last_error_message.must_equal "Could not locate Stored Key invalidkey"
26
+ @ns.last_error_details.must_be_nil
27
+ end
28
+ end
29
+ end
30
+
31
+ # TODO: We don't get an error when we lookup a key that doesn't exist...and other error cases...
@@ -0,0 +1,52 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost:3000/vcrtest/api/v1/account
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ x-nimbus-component-key:
11
+ - 34807a2d4d-a9990c4748218eb6ed-70886bc0fd
12
+ x-nimbus-client-version:
13
+ - 0.4.0
14
+ x-nimbus-client:
15
+ - muskratsoftware/NimbusSecureClient
16
+ x-nimbus-language:
17
+ - ruby
18
+ accept-encoding:
19
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
20
+ accept:
21
+ - ! '*/*'
22
+ user-agent:
23
+ - Ruby
24
+ response:
25
+ status:
26
+ code: 200
27
+ message: OK
28
+ headers:
29
+ content-type:
30
+ - application/json; charset=utf-8
31
+ x-ua-compatible:
32
+ - IE=Edge
33
+ etag:
34
+ - ! '"e3a4296c05b32d0ff0c13b3792a87ec5"'
35
+ cache-control:
36
+ - max-age=0, private, must-revalidate
37
+ x-request-id:
38
+ - 31dee43871629934ff8e333f5151a2a3
39
+ x-runtime:
40
+ - '0.024024'
41
+ content-length:
42
+ - '92'
43
+ connection:
44
+ - close
45
+ server:
46
+ - thin 1.4.1 codename Chromeo
47
+ body:
48
+ encoding: US-ASCII
49
+ string: ! '{"status":"success","account":{"name":"VCR Account","num_crypt_keys":23,"num_stored_keys":34}}'
50
+ http_version: '1.1'
51
+ recorded_at: Thu, 02 Aug 2012 03:54:45 GMT
52
+ recorded_with: VCR 2.2.4
@@ -0,0 +1,52 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost:3000/vcrtest/api/v1/stored_keys/test1/locate
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ x-nimbus-component-key:
11
+ - 34807a2d4d-a9990c4748218eb6ed-70886bc0fd
12
+ x-nimbus-client-version:
13
+ - 0.4.0
14
+ x-nimbus-client:
15
+ - muskratsoftware/NimbusSecureClient
16
+ x-nimbus-language:
17
+ - ruby
18
+ accept-encoding:
19
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
20
+ accept:
21
+ - ! '*/*'
22
+ user-agent:
23
+ - Ruby
24
+ response:
25
+ status:
26
+ code: 200
27
+ message: OK
28
+ headers:
29
+ content-type:
30
+ - application/json; charset=utf-8
31
+ x-ua-compatible:
32
+ - IE=Edge
33
+ etag:
34
+ - ! '"af24594f0840cb2713181cae549d7d53"'
35
+ cache-control:
36
+ - max-age=0, private, must-revalidate
37
+ x-request-id:
38
+ - 5588bd8d8d6058def7ed0ac007ea17b2
39
+ x-runtime:
40
+ - '0.029527'
41
+ content-length:
42
+ - '324'
43
+ connection:
44
+ - close
45
+ server:
46
+ - thin 1.4.1 codename Chromeo
47
+ body:
48
+ encoding: US-ASCII
49
+ string: ! '{"status":"success","stored_key":{"id":3,"ident":"test1","encrypted_value":"U2FsdGVkX1/GKKaIUe5+lSzPJ0shgBrFDx0oGQO0LBNvOPmo69NiN7SiuLMBQTCV\r\n","key_type":"symmetric","crypt_key":{"id":9,"ident":"primary","salt":"$2a$10$zT38XT42BXYjcfd5uFO2E.","digest":"d6992c3ad871a429b4485967456b87fbc916a126b60c788516e11dd4cb3e1410"}}}'
50
+ http_version: '1.1'
51
+ recorded_at: Thu, 02 Aug 2012 03:59:40 GMT
52
+ recorded_with: VCR 2.2.4
@@ -0,0 +1,101 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost:3000/vcrtest/api/v1/stored_keys/test1/locate
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ x-nimbus-component-key:
11
+ - 34807a2d4d-a9990c4748218eb6ed-70886bc0fd
12
+ x-nimbus-client-version:
13
+ - 0.4.0
14
+ x-nimbus-client:
15
+ - muskratsoftware/NimbusSecureClient
16
+ x-nimbus-language:
17
+ - ruby
18
+ accept-encoding:
19
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
20
+ accept:
21
+ - ! '*/*'
22
+ user-agent:
23
+ - Ruby
24
+ response:
25
+ status:
26
+ code: 200
27
+ message: OK
28
+ headers:
29
+ content-type:
30
+ - application/json; charset=utf-8
31
+ x-ua-compatible:
32
+ - IE=Edge
33
+ etag:
34
+ - ! '"af24594f0840cb2713181cae549d7d53"'
35
+ cache-control:
36
+ - max-age=0, private, must-revalidate
37
+ x-request-id:
38
+ - 2a95b9c8862fb4b248da9467446f8c9c
39
+ x-runtime:
40
+ - '0.033637'
41
+ content-length:
42
+ - '324'
43
+ connection:
44
+ - close
45
+ server:
46
+ - thin 1.4.1 codename Chromeo
47
+ body:
48
+ encoding: US-ASCII
49
+ string: ! '{"status":"success","stored_key":{"id":3,"ident":"test1","encrypted_value":"U2FsdGVkX1/GKKaIUe5+lSzPJ0shgBrFDx0oGQO0LBNvOPmo69NiN7SiuLMBQTCV\r\n","key_type":"symmetric","crypt_key":{"id":9,"ident":"primary","salt":"$2a$10$zT38XT42BXYjcfd5uFO2E.","digest":"d6992c3ad871a429b4485967456b87fbc916a126b60c788516e11dd4cb3e1410"}}}'
50
+ http_version: '1.1'
51
+ recorded_at: Thu, 02 Aug 2012 03:59:40 GMT
52
+ - request:
53
+ method: get
54
+ uri: http://localhost:3000/vcrtest/api/v1/stored_keys/test2/locate
55
+ body:
56
+ encoding: US-ASCII
57
+ string: ''
58
+ headers:
59
+ x-nimbus-component-key:
60
+ - 34807a2d4d-a9990c4748218eb6ed-70886bc0fd
61
+ x-nimbus-client-version:
62
+ - 0.4.0
63
+ x-nimbus-client:
64
+ - muskratsoftware/NimbusSecureClient
65
+ x-nimbus-language:
66
+ - ruby
67
+ accept-encoding:
68
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
69
+ accept:
70
+ - ! '*/*'
71
+ user-agent:
72
+ - Ruby
73
+ response:
74
+ status:
75
+ code: 200
76
+ message: OK
77
+ headers:
78
+ content-type:
79
+ - application/json; charset=utf-8
80
+ x-ua-compatible:
81
+ - IE=Edge
82
+ etag:
83
+ - ! '"63fba6143471cebd1321622de55ef88e"'
84
+ cache-control:
85
+ - max-age=0, private, must-revalidate
86
+ x-request-id:
87
+ - 570fcdfafe42ade8d7f96cc9fe8fcb8e
88
+ x-runtime:
89
+ - '0.106230'
90
+ content-length:
91
+ - '327'
92
+ connection:
93
+ - close
94
+ server:
95
+ - thin 1.4.1 codename Chromeo
96
+ body:
97
+ encoding: US-ASCII
98
+ string: ! '{"status":"success","stored_key":{"id":4,"ident":"test2","encrypted_value":"U2FsdGVkX18WTqz1XtiUi7s1riXV6w49980V3E4ysvhyNgVxTY8eocj8jgsGn4PG\r\n","key_type":"symmetric","crypt_key":{"id":10,"ident":"secondary","salt":"$2a$10$bcYes9rn8wAX0W/eIVSUBu","digest":"09890ee6ed6bb70d8a8671ab8bd6102da2d6e4f2e8311ccb5ca83195276e4581"}}}'
99
+ http_version: '1.1'
100
+ recorded_at: Thu, 02 Aug 2012 03:59:40 GMT
101
+ recorded_with: VCR 2.2.4
@@ -0,0 +1,52 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://localhost:3000/vcrtest/api/v1/stored_keys/invalidkey/locate
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ x-nimbus-component-key:
11
+ - 34807a2d4d-a9990c4748218eb6ed-70886bc0fd
12
+ x-nimbus-client-version:
13
+ - 0.4.0
14
+ x-nimbus-client:
15
+ - muskratsoftware/NimbusSecureClient
16
+ x-nimbus-language:
17
+ - ruby
18
+ accept-encoding:
19
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
20
+ accept:
21
+ - ! '*/*'
22
+ user-agent:
23
+ - Ruby
24
+ response:
25
+ status:
26
+ code: 200
27
+ message: OK
28
+ headers:
29
+ content-type:
30
+ - application/json; charset=utf-8
31
+ x-ua-compatible:
32
+ - IE=Edge
33
+ etag:
34
+ - ! '"fe603117385eb96a83f0de7440c7ad4e"'
35
+ cache-control:
36
+ - max-age=0, private, must-revalidate
37
+ x-request-id:
38
+ - 3dd7d8ef85311f6e9d0d8e2a6e064421
39
+ x-runtime:
40
+ - '0.021249'
41
+ content-length:
42
+ - '90'
43
+ connection:
44
+ - close
45
+ server:
46
+ - thin 1.4.1 codename Chromeo
47
+ body:
48
+ encoding: US-ASCII
49
+ string: ! '{"status":"error","errormsg":"Could not locate Stored Key invalidkey","errordetails":null}'
50
+ http_version: '1.1'
51
+ recorded_at: Thu, 02 Aug 2012 03:59:40 GMT
52
+ recorded_with: VCR 2.2.4
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH << File.dirname(File.expand_path(__FILE__).to_s).to_s+"/../lib/"
2
+ require 'minitest/autorun'
3
+ require 'vcr'
4
+ require 'nimbussecure'
5
+
6
+ VCR.configure do |c|
7
+ c.cassette_library_dir = 'test/fixtures/vcr_cassettes'
8
+ c.hook_into :fakeweb
9
+ # c.stub_with :fakeweb
10
+ end
data/test/run_tests.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'minitest/autorun'
2
+ test_dir_root=File.dirname(Pathname.new(File.expand_path(__FILE__)).realpath.to_s).to_s
3
+ $LOAD_PATH << test_dir_root
4
+ FileList["#{test_dir_root}/*_spec.rb"].each do |file|
5
+ require file
6
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nimbussecure
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Lee Atchison
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: minitest
16
+ requirement: &70236373001520 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70236373001520
25
+ - !ruby/object:Gem::Dependency
26
+ name: vcr
27
+ requirement: &70236373001100 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70236373001100
36
+ - !ruby/object:Gem::Dependency
37
+ name: fakeweb
38
+ requirement: &70236373000680 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70236373000680
47
+ - !ruby/object:Gem::Dependency
48
+ name: faraday
49
+ requirement: &70236373000240 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70236373000240
58
+ - !ruby/object:Gem::Dependency
59
+ name: gibberish
60
+ requirement: &70236372999780 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70236372999780
69
+ description: Client library for NimbusSecure
70
+ email:
71
+ - lee@nimbussecure.com
72
+ executables:
73
+ - nimbussecure
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - README.md
80
+ - Rakefile
81
+ - bin/nimbussecure
82
+ - lib/nimbussecure.rb
83
+ - lib/nimbussecure/accounts.rb
84
+ - lib/nimbussecure/attr_accessor.rb
85
+ - lib/nimbussecure/base.rb
86
+ - lib/nimbussecure/config.rb
87
+ - lib/nimbussecure/connect.rb
88
+ - lib/nimbussecure/crypt_key.rb
89
+ - lib/nimbussecure/errors.rb
90
+ - lib/nimbussecure/results.rb
91
+ - lib/nimbussecure/stored_key.rb
92
+ - lib/nimbussecure/version.rb
93
+ - nimbussecure.gemspec
94
+ - pry_load.rb
95
+ - test/accounts_spec.rb
96
+ - test/basic_key_lookup_spec.rb
97
+ - test/fixtures/vcr_cassettes/accounts/test.yml
98
+ - test/fixtures/vcr_cassettes/lookup/key1.yml
99
+ - test/fixtures/vcr_cassettes/lookup/key2.yml
100
+ - test/fixtures/vcr_cassettes/lookup/key3.yml
101
+ - test/minitest_helper.rb
102
+ - test/run_tests.rb
103
+ homepage: ''
104
+ licenses: []
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ! '>='
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project: nimbussecure
123
+ rubygems_version: 1.8.15
124
+ signing_key:
125
+ specification_version: 3
126
+ summary: Client library for NimbusSecure
127
+ test_files:
128
+ - test/accounts_spec.rb
129
+ - test/basic_key_lookup_spec.rb
130
+ - test/fixtures/vcr_cassettes/accounts/test.yml
131
+ - test/fixtures/vcr_cassettes/lookup/key1.yml
132
+ - test/fixtures/vcr_cassettes/lookup/key2.yml
133
+ - test/fixtures/vcr_cassettes/lookup/key3.yml
134
+ - test/minitest_helper.rb
135
+ - test/run_tests.rb