nimbussecure 0.5.0

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,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