rapid-vaults 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 16da5a6fcd72e890b88a34822a8d0018c2349988
4
- data.tar.gz: fe28a0e78364d8cf28d316937ca632758176ead0
3
+ metadata.gz: a33025f28dcfc0be205d5a54c706192c06319a94
4
+ data.tar.gz: 428808ee49e8caa2791983be429fd232bf004e94
5
5
  SHA512:
6
- metadata.gz: 81c8373c61e40e22fb1489f990d7e3b5ed344c12c3e9382f994d0a2c9bbdf3787cd396735761b8e3439ec9eaff9c97793ae16b2e8cea4f4448db7882eed518ce
7
- data.tar.gz: 1df691acfd5120d5ba32669c5e5f03f221d34abd3f8b4fd2884b0b86e4913c294a31d0fb7541d74bd251651f88411fb4838091c557dc69b0e20786f8e4235c77
6
+ metadata.gz: 0ad2fa93633085305393343d0583c5618047f424b2069854d1e482aa8abbec5b837e0b753a1a706abcd51d5f9035f81d32bafc98cf240fd838925f8991ac8e2c
7
+ data.tar.gz: 0e19f0774f6b94e63186401f7a37d43e499689d75201bcce153f453c32adf0c2d28cef6e14259147d2aedfa4a967af57c0ded96929d63d57ab7d52f6801d6676
data/README.md CHANGED
@@ -5,6 +5,10 @@
5
5
  - [Usage](#usage)
6
6
  - [CLI](#cli)
7
7
  - [API](#api)
8
+ - [Ansible](#ansible)
9
+ - [Puppet](#puppet)
10
+ - [Hiera](#hiera)
11
+ - [Chef](#chef)
8
12
  - [Contributing](#contributing)
9
13
 
10
14
  ## Description
@@ -17,7 +21,7 @@ Ansible-Vault is very similar to Rapid Vaults. Both are streamlined and easy to
17
21
 
18
22
  ### Non-Comparative Software
19
23
 
20
- Rapid Vaults is not similar to tools like RbNaCl or Hashicorp's Vault. RbNaCl offers advanced encryption techniques by providing bindings to libsodium. Rapid Vaults relies upon AES-256-GCM or GPG. Hashicorp's Vault is Enterprise level software with many powerful features and conveniences. Rapid Vaults is a lightweight and narrowly focused tool.
24
+ Rapid Vaults is not similar to tools like RbNaCl or Hashicorp's Vault. RbNaCl offers advanced encryption techniques by providing bindings to libsodium. Rapid Vaults relies upon AES-256-GCM (OpenSSL) or GPG's algorithms (RSA, SHA-512, etc.). Hashicorp's Vault is Enterprise level software with many powerful features and conveniences. Rapid Vaults is a lightweight and narrowly focused tool.
21
25
 
22
26
  ## Usage
23
27
 
@@ -28,29 +32,30 @@ Note trailing information for each flag/argument for possible differences with u
28
32
  ```
29
33
  usage: rapid-vaults [options] file
30
34
  --gpg Use GNUPG/GPG instead of GNUTLS/OpenSSL for encryption/decryption.
31
- -g, --generate Generate a key and nonce for encryption and decryption (GPG: n/a).
32
- -e, --encrypt Encrypt a file using a key and nonce and generate a tag (GPG: key only).
33
- -d, --decrypt Decrypt a file using a key, nonce, and tag (GPG: key only).
34
- -k, --key key Key file to be used for encryption or decryption.
35
+ -g, --generate Generate a key and nonce for encryption and decryption (GPG: keys only).
36
+ -e, --encrypt Encrypt a file using a key and nonce and generate a tag (GPG: key and pw only).
37
+ -d, --decrypt Decrypt a file using a key, nonce, and tag (GPG: key and pw only).
38
+ -k, --key key Key file to be used for encryption or decryption. (GPG: use GNUPGHOME)
35
39
  -n, --nonce nonce Nonce file to be used for encryption or decryption (GPG: n/a).
36
40
  -t, --tag tag Tag file to be used for decryption (GPG: n/a).
37
- -p, --password password (optional) Password to be used for encryption or decryption (GPG: required).').
38
- -f, --file-password password.txt (optional) Text file containing a password to be used for encryption or decryption (GPG: required).').
41
+ -p, --password password (optional) Password to be used for encryption or decryption (GPG: required).
42
+ -f, --file-password password.txt (optional) Text file containing a password to be used for encryption or decryption (GPG: required).
39
43
  --gpgparams GPG Key params input file used during generation of keys.
44
+ -o --outdir Optional output directory for generated files (default: pwd). (GPG: optional)
40
45
  ```
41
46
 
42
- #### Generate Key and Nonce
47
+ #### Generate Key and Nonce with SSL
43
48
  `rapid-vaults -g`
44
49
 
45
50
  #### Encrypt File with SSL
46
51
 
47
- `rapid-vaults -e -k cert.key -n nonce.txt -p secret unencrypted.txt`
52
+ `rapid-vaults -e -k cert.key -n nonce.txt -p secret -o /output/dir unencrypted.txt`
48
53
 
49
54
  #### Decrypt a File with SSL
50
55
 
51
- `rapid-vaults -d -k cert.key -n nonce.txt -t tag.txt -p secret encrypted.txt`
56
+ `rapid-vaults -d -k cert.key -n nonce.txt -t tag.txt -p secret -o /output/dir encrypted.txt`
52
57
 
53
- #### Generate Key with GPG
58
+ #### Generate Keys with GPG
54
59
  This is the only situation where a `--gpgparams` flag and argument is required or utilized. The file provided as the argument should look like the following:
55
60
 
56
61
  ```
@@ -72,12 +77,16 @@ The environment variable `GNUPGHOME` must be set in the shell prior to generatin
72
77
  #### Encrypt File with GPG
73
78
  Currently you set the path to the keys and other files via the environment variable `GNUPGHOME` prior to executing. Otherwise, the code will look in the default directory for the current user.
74
79
 
75
- `rapid-vaults --gpg -e -p password unencrypted.txt`
80
+ `rapid-vaults --gpg -e -p password -o /output/dir unencrypted.txt`
76
81
 
77
82
  #### Decrypt a File with GPG
78
83
  Currently you set the path to the keys and other files via the environment variable `GNUPGHOME` prior to executing. Otherwise, the code will look in the default directory for the current user.
79
84
 
80
- `rapid-vaults --gpg -d -p password encrypted.txt`
85
+ `rapid-vaults --gpg -d -p password -o /output/dir encrypted.txt`
86
+
87
+ #### Output an Integration
88
+
89
+ `rapid-vaults --puppet -o /output/dir`
81
90
 
82
91
  ### API
83
92
 
@@ -114,7 +123,7 @@ require 'rapid-vaults'
114
123
 
115
124
  options = {}
116
125
  options[:action] = :decrypt
117
- options[:file] = '/path/to/data.txt'
126
+ options[:file] = '/path/to/encrypted_data.txt'
118
127
  options[:key] = '/path/to/cert.key'
119
128
  options[:nonce] = '/path/to/nonce.txt'
120
129
  options[:tag] = '/path/to/tag.txt'
@@ -131,7 +140,7 @@ ENV['GNUPGHOME'] = '/home/alice/.gnupg'
131
140
  options = {}
132
141
  options[:action] = :generate
133
142
  options[:algorithm] = :gpgme
134
- options[:gpgparams] = gpgparams: File.read('gpgparams.txt')
143
+ options[:gpgparams] = File.read('gpgparams.txt')
135
144
  RapidVaults::API.main(options)
136
145
  ```
137
146
 
@@ -156,7 +165,7 @@ Passphrase: abc
156
165
  ```ruby
157
166
  require 'rapid-vaults'
158
167
 
159
- ENV['GNUPGHOME'] = '/home/bob/.gnupg'
168
+ ENV['GNUPGHOME'] = '/home/bob/.gnupg' # optional
160
169
 
161
170
  options = {}
162
171
  options[:action] = :encrypt
@@ -171,16 +180,32 @@ encrypted_contents = RapidVaults::API.main(options)
171
180
  ```ruby
172
181
  require 'rapid-vaults'
173
182
 
174
- ENV['GNUPGHOME'] = '/home/chris/.gnupg'
183
+ ENV['GNUPGHOME'] = '/home/chris/.gnupg' # optional
175
184
 
176
185
  options = {}
177
186
  options[:action] = :decrypt
178
187
  options[:algorithm] = :gpgme
179
- options[:file] = '/path/to/data.txt'
188
+ options[:file] = '/path/to/encrypted_data.txt'
180
189
  options[:pw] = File.read('/path/to/password.txt')
181
190
  decrypted_contents = RapidVaults::API.main(options)
182
191
  ```
183
192
 
193
+ ### Ansible
194
+
195
+ forthcoming
196
+
197
+ ### Puppet
198
+
199
+ Puppet bindings are presented as a 2x2 matrix of custom functions for encryption/decryption and SSL/GPG. The custom functions require a non-obsolete version of Puppet. Documentation pertaining to their usage is done via Puppet Strings within the functions. It is highly recommended to wrap the output of the decryption functions within a `Sensitive` data type so that decrypted secrets are not shown in logs.
200
+
201
+ ### Hiera
202
+
203
+ forthcoming
204
+
205
+ ### Chef
206
+
207
+ Chef can access Rapid Vaults directly through the native Ruby API. Therefore, the Chef bindings are presented as example methods for doing so.
208
+
184
209
  ## Contributing
185
210
  Code should pass all spec tests. New features should involve new spec tests. Adherence to Rubocop and Reek is expected where not overly onerous or where the check is of dubious cost/benefit.
186
211
 
data/lib/rapid-vaults.rb CHANGED
@@ -10,46 +10,67 @@ class RapidVaults
10
10
  self.class.process(settings)
11
11
 
12
12
  # execute desired action and algorithm via dynamic call
13
- # public_send("#{settings[:action].capitalize}.#{settings[:algorithm]}".to_sym)
13
+ # public_send("#{settings[:action].capitalize}.#{settings[:algorithm]}".to_sym, settings)
14
14
  case settings[:action]
15
15
  when :generate then Generate.public_send(settings[:algorithm], settings)
16
16
  when :encrypt then Encrypt.public_send(settings[:algorithm], settings)
17
17
  when :decrypt then Decrypt.public_send(settings[:algorithm], settings)
18
+ when :integrate then Integrate.public_send(settings[:integrate], settings)
18
19
  end
19
20
  end
20
21
 
21
22
  # method for processing the settings and inputs
22
23
  def self.process(settings)
23
- # check for problems with arguments
24
- if settings[:algorithm] == :gpgme
25
- case settings[:action]
26
- when :generate
27
- raise 'GPG params file argument required for generation.' unless settings.key?(:gpgparams)
28
- return
29
- when :decrypt, :encrypt
30
- raise 'File and password arguments required for encryption or decryption.' unless settings.key?(:file) && settings.key?(:pw)
31
- else raise 'Action must be one of generate, encrypt, or decrypt.'
32
- end
33
- else
34
- case settings[:action]
35
- when :generate then return
36
- when :encrypt
37
- raise 'File, key, and nonce arguments are required for encryption.' unless settings.key?(:file) && settings.key?(:key) && settings.key?(:nonce)
38
- when :decrypt
39
- raise 'File, key, nonce, and tag arguments are required for decryption.' unless settings.key?(:file) && settings.key?(:key) && settings.key?(:nonce) && settings.key?(:tag)
40
- else raise 'Action must be one of generate, encrypt, or decrypt.'
41
- end
24
+ # default to openssl algorithm and `pwd` output directory
25
+ settings[:outdir] ||= Dir.pwd
26
+ raise "The output directory #{settings[:outdir]} does not exist or is not a directory!" unless File.directory?(settings[:outdir])
27
+ settings[:outdir] += '/' unless settings[:outdir][-1] == '/'
28
+
29
+ return if settings[:action] == :integrate
30
+ settings[:algorithm] ||= :openssl
31
+
32
+ # check for problems with arguments and inputs
33
+ public_send("process_#{settings[:algorithm]}".to_sym, settings)
34
+ end
35
+
36
+ # processing openssl
37
+ def self.process_openssl(settings)
38
+ private_class_method :method
39
+ # check arguments
40
+ case settings[:action]
41
+ when :generate then return
42
+ when :encrypt
43
+ raise 'File, key, and nonce arguments are required for encryption.' unless settings.key?(:file) && settings.key?(:key) && settings.key?(:nonce)
44
+ when :decrypt
45
+ raise 'File, key, nonce, and tag arguments are required for decryption.' unless settings.key?(:file) && settings.key?(:key) && settings.key?(:nonce) && settings.key?(:tag)
46
+ else raise 'Action must be one of generate, encrypt, or decrypt.'
42
47
  end
43
48
 
44
- # check for problems with inputs and read in files
49
+ # lambda for input processing
50
+ process_input = ->(input) { File.file?(settings[input]) ? settings[input] = File.read(settings[input]) : (raise "Input #{input} is not an existing file.") }
51
+
52
+ # check inputs and read in files
45
53
  raise 'Password must be a string.' if settings.key?(:pw) && !settings[:pw].is_a?(String)
46
- File.file?(settings[:file]) ? settings[:file] = File.read(settings[:file]) : (raise 'Input file is not an existing file.')
47
- # gnugp only uses password and file
48
- return if settings[:algorithm] == :gpgme
49
- File.file?(settings[:key]) ? settings[:key] = File.read(settings[:key]) : (raise 'Input key is not an existing file.')
50
- File.file?(settings[:nonce]) ? settings[:nonce] = File.read(settings[:nonce]) : (raise 'Input nonce is not an existing file.')
54
+ %i[file key nonce].each(&process_input)
51
55
  # only decrypt needs a tag input
52
- return unless settings[:action] == :decrypt
53
- File.file?(settings[:tag]) ? settings[:tag] = File.read(settings[:tag]) : (raise 'Input tag is not an existing file.')
56
+ process_input.call(:tag) if settings[:action] == :decrypt
57
+ end
58
+
59
+ # processing gpgme
60
+ def self.process_gpgme(settings)
61
+ private_class_method :method
62
+ # check arguments
63
+ case settings[:action]
64
+ when :generate
65
+ raise 'GPG params file argument required for generation.' unless settings.key?(:gpgparams)
66
+ return
67
+ when :decrypt, :encrypt
68
+ raise 'File and password arguments required for encryption or decryption.' unless settings.key?(:file) && settings.key?(:pw)
69
+ else raise 'Action must be one of generate, encrypt, or decrypt.'
70
+ end
71
+
72
+ # check inputs and read in files
73
+ raise 'Password must be a string.' unless settings[:pw].is_a?(String)
74
+ File.file?(settings[:file]) ? settings[:file] = File.read(settings[:file]) : (raise 'Input file is not an existing file.')
54
75
  end
55
76
  end
@@ -12,7 +12,6 @@ class RapidVaults::API
12
12
  def self.parse(settings)
13
13
  # establish settings for api and denote using api
14
14
  settings[:ui] = :api
15
- settings[:algorithm] = :openssl unless settings.key?(:algorithm)
16
15
  settings
17
16
  end
18
17
  end
@@ -26,8 +26,6 @@ class RapidVaults::CLI
26
26
  settings = {}
27
27
  # specify cli being used
28
28
  settings[:ui] = :cli
29
- # default to openssl algorithm
30
- settings[:algorithm] = :openssl
31
29
 
32
30
  opt_parser = OptionParser.new do |opts|
33
31
  # usage
@@ -35,7 +33,7 @@ class RapidVaults::CLI
35
33
 
36
34
  # base options
37
35
  opts.on('--version', 'Display the current version.') do
38
- puts 'rapid-vaults 1.1.0'
36
+ puts 'rapid-vaults 1.1.1'
39
37
  exit 0
40
38
  end
41
39
 
@@ -43,19 +41,24 @@ class RapidVaults::CLI
43
41
  opts.on('--gpg', 'Use GNUPG/GPG instead of GNUTLS/OpenSSL for encryption/decryption.') { settings[:algorithm] = :gpgme }
44
42
 
45
43
  # generate, encrypt, or decrypt
46
- opts.on('-g', '--generate', 'Generate a key and nonce for encryption and decryption (GPG: n/a).') { settings[:action] = :generate }
47
- opts.on('-e', '--encrypt', 'Encrypt a file using a key and nonce and generate a tag (GPG: key only).') { settings[:action] = :encrypt }
48
- opts.on('-d', '--decrypt', 'Decrypt a file using a key, nonce, and tag (GPG: key only).') { settings[:action] = :decrypt }
44
+ opts.on('-g', '--generate', 'Generate a key and nonce for encryption and decryption (GPG: keys only).') { settings[:action] = :generate }
45
+ opts.on('-e', '--encrypt', 'Encrypt a file using a key and nonce and generate a tag (GPG: key and pw only).') { settings[:action] = :encrypt }
46
+ opts.on('-d', '--decrypt', 'Decrypt a file using a key, nonce, and tag (GPG: key and pw only).') { settings[:action] = :decrypt }
49
47
 
50
48
  # key, nonce, password, and tag
51
- opts.on('-k', '--key key', String, 'Key file to be used for encryption or decryption.') { |arg| settings[:key] = arg }
49
+ opts.on('-k', '--key key', String, 'Key file to be used for encryption or decryption. (GPG: use GNUPGHOME)') { |arg| settings[:key] = arg }
52
50
  opts.on('-n', '--nonce nonce', String, 'Nonce file to be used for encryption or decryption (GPG: n/a).') { |arg| settings[:nonce] = arg }
53
51
  opts.on('-t', '--tag tag', String, 'Tag file to be used for decryption (GPG: n/a).') { |arg| settings[:tag] = arg }
54
52
  opts.on('-p', '--password password', String, '(optional) Password to be used for encryption or decryption (GPG: required).') { |arg| settings[:pw] = arg }
55
53
  opts.on('-f', '--file-password password.txt', String, '(optional) Text file containing a password to be used for encryption or decryption (GPG: required).') { |arg| settings[:pw] = File.read(arg) }
56
54
 
57
- # gpg params file
55
+ # integrations
56
+ opts.on('--puppet', String, 'Output files to support Puppet integrations.') { settings[:action] = :integrate; settings[:integrate] = :puppet }
57
+ opts.on('--chef', String, 'Output files to support Chef integrations.') { settings[:action] = :integrate; settings[:integrate] = :chef }
58
+
59
+ # other
58
60
  opts.on('--gpgparams params.txt', String, 'GPG Key params input file used during generation of keys.') { |arg| settings[:gpgparams] = File.read(arg) }
61
+ opts.on('-o --outdir', String, 'Optional output directory for generated files (default: pwd). (GPG: optional)') { |arg| settings[:outdir] = arg }
59
62
  end
60
63
 
61
64
  # parse args and return settings
@@ -17,8 +17,8 @@ class Decrypt
17
17
  # output the decryption
18
18
  if settings[:ui] == :cli
19
19
  # output to file
20
- File.write('decrypted.txt', decipher.update(settings[:file]) + decipher.final)
21
- puts 'Your decrypted.txt has been written out to the current directory.'
20
+ File.write("#{settings[:outdir]}decrypted.txt", decipher.update(settings[:file]) + decipher.final)
21
+ puts "Your decrypted.txt has been written out to #{settings[:outdir]}."
22
22
  elsif settings[:ui] == :api
23
23
  # output to string
24
24
  decipher.update(settings[:file]) + decipher.final
@@ -29,6 +29,9 @@ class Decrypt
29
29
  def self.gpgme(settings)
30
30
  require 'gpgme'
31
31
 
32
+ # check if GPGHOME env was set
33
+ puts "Environment variable 'GNUPGHOME' was not set. Files in #{ENV['HOME']}/.gnupg will be used for authentication." unless ENV['GNUPGHOME']
34
+
32
35
  # setup the decryption parameters
33
36
  encrypted = GPGME::Data.new(settings[:file])
34
37
  crypto = GPGME::Crypto.new(armor: true, pinentry_mode: GPGME::PINENTRY_MODE_LOOPBACK)
@@ -36,8 +39,8 @@ class Decrypt
36
39
  # output the decryption
37
40
  if settings[:ui] == :cli
38
41
  # output to file
39
- File.write('decrypted.txt', crypto.decrypt(encrypted, password: settings[:pw]).read)
40
- puts 'Your decrypted.txt has been written out to the current directory.'
42
+ File.write("#{settings[:outdir]}decrypted.txt", crypto.decrypt(encrypted, password: settings[:pw]).read)
43
+ puts "Your decrypted.txt has been written out to #{settings[:outdir]}."
41
44
  elsif settings[:ui] == :api
42
45
  # output to string
43
46
  crypto.decrypt(encrypted, password: settings[:pw]).read
@@ -13,9 +13,9 @@ class Encrypt
13
13
  # output the encryption and associated tag
14
14
  if settings[:ui] == :cli
15
15
  # output to file
16
- File.write('encrypted.txt', cipher.update(settings[:file]) + cipher.final)
17
- File.write('tag.txt', cipher.auth_tag)
18
- puts 'Your encrypted.txt and associated tag.txt for this encryption have been generated in your current directory.'
16
+ File.write("#{settings[:outdir]}encrypted.txt", cipher.update(settings[:file]) + cipher.final)
17
+ File.write("#{settings[:outdir]}tag.txt", cipher.auth_tag)
18
+ puts "Your encrypted.txt and associated tag.txt for this encryption have been generated in #{settings[:outdir]}."
19
19
  elsif settings[:ui] == :api
20
20
  # output to array
21
21
  [cipher.update(settings[:file]) + cipher.final, cipher.auth_tag]
@@ -26,14 +26,17 @@ class Encrypt
26
26
  def self.gpgme(settings)
27
27
  require 'gpgme'
28
28
 
29
+ # check if GPGHOME env was set
30
+ puts "Environment variable 'GNUPGHOME' was not set. Files in #{ENV['HOME']}/.gnupg will be used for authentication." unless ENV['GNUPGHOME']
31
+
29
32
  # setup the encryption parameters
30
33
  crypto = GPGME::Crypto.new(armor: true, pinentry_mode: GPGME::PINENTRY_MODE_LOOPBACK)
31
34
 
32
35
  # output the encryption and associated tag
33
36
  if settings[:ui] == :cli
34
37
  # output to file
35
- File.write('encrypted.txt', crypto.encrypt(settings[:file], symmetric: true, password: settings[:pw]).read)
36
- puts 'Your encrypted.txt for this encryption have been generated in your current directory.'
38
+ File.write("#{settings[:outdir]}encrypted.txt", crypto.encrypt(settings[:file], symmetric: true, password: settings[:pw]).read)
39
+ puts "Your encrypted.txt for this encryption have been generated in #{settings[:outdir]}."
37
40
  elsif settings[:ui] == :api
38
41
  # output to string
39
42
  crypto.encrypt(settings[:file], symmetric: true, password: settings[:pw]).read
@@ -9,9 +9,9 @@ class Generate
9
9
 
10
10
  if settings[:ui] == :cli
11
11
  # output to file
12
- File.write('key.txt', cipher.random_key)
13
- File.write('nonce.txt', cipher.random_iv)
14
- puts 'Your key.txt and nonce.txt have been generated in your current directory.'
12
+ File.write("#{settings[:outdir]}key.txt", cipher.random_key)
13
+ File.write("#{settings[:outdir]}nonce.txt", cipher.random_iv)
14
+ puts "Your key.txt and nonce.txt have been generated in #{settings[:outdir]}."
15
15
  elsif settings[:ui] == :api
16
16
  # output to string
17
17
  [cipher.random_key, cipher.random_iv]
@@ -23,7 +23,7 @@ class Generate
23
23
  require 'gpgme'
24
24
 
25
25
  # ensure we have a place to store these output files
26
- raise 'Environment variable GNUPGHOME was not set.' unless ENV['GNUPGHOME']
26
+ raise 'Environment variable "GNUPGHOME" was not set.' unless ENV['GNUPGHOME']
27
27
 
28
28
  # create gpg keys
29
29
  GPGME::Ctx.new.generate_key(settings[:gpgparams], nil, nil)
@@ -0,0 +1,20 @@
1
+ # class to output integrations with other software
2
+ class Integration
3
+ # outputs puppet integrations
4
+ def self.puppet(settings)
5
+ # output puppet integrations to output directory
6
+ %w[gpg ssl].each do |algo|
7
+ %w[encrypt decrypt].each do |action|
8
+ content = File.read("#{__dir__}/integrations/puppet_#{algo}_#{action}.rb")
9
+ File.write("#{settings[:outdir]}puppet_#{algo}_#{action}.rb", content)
10
+ end
11
+ end
12
+ end
13
+
14
+ # outputs chef integrations
15
+ def self.chef(settings)
16
+ # output chef integrations to output directory
17
+ content = File.read("#{__dir__}/integrations/chef.rb")
18
+ File.write("#{settings[:outdir]}chef.rb", content)
19
+ end
20
+ end
@@ -0,0 +1,66 @@
1
+ require 'rapid-vaults'
2
+
3
+ # returns key, nonce
4
+ def ssl_generate
5
+ options = {}
6
+ options[:action] = :generate
7
+ RapidVaults::API.main(options)
8
+ end
9
+
10
+ # returns encrypted_contents, tag
11
+ def ssl_encrypt
12
+ options = {}
13
+ options[:action] = :encrypt
14
+ options[:file] = '/path/to/data.txt'
15
+ options[:key] = '/path/to/cert.key'
16
+ options[:nonce] = '/path/to/nonce.txt'
17
+ options[:pw] = File.read('/path/to/password.txt') # optional
18
+ RapidVaults::API.main(options)
19
+ end
20
+
21
+ # returns decrypted_contents
22
+ def ssl_decrypt
23
+ options = {}
24
+ options[:action] = :decrypt
25
+ options[:file] = '/path/to/encrypted_data.txt'
26
+ options[:key] = '/path/to/cert.key'
27
+ options[:nonce] = '/path/to/nonce.txt'
28
+ options[:tag] = '/path/to/tag.txt'
29
+ options[:pw] = File.read('/path/to/password.txt') # optional
30
+ RapidVaults::API.main(options)
31
+ end
32
+
33
+ # returns exit code on status of gnupg setup
34
+ def gpg_generate
35
+ ENV['GNUPGHOME'] = '/home/alice/.gnupg'
36
+
37
+ options = {}
38
+ options[:action] = :generate
39
+ options[:algorithm] = :gpgme
40
+ options[:gpgparams] = File.read('gpgparams.txt')
41
+ RapidVaults::API.main(options)
42
+ end
43
+
44
+ # returns encrypted_contents
45
+ def gpg_encryot
46
+ ENV['GNUPGHOME'] = '/home/bob/.gnupg'
47
+
48
+ options = {}
49
+ options[:action] = :encrypt
50
+ options[:algorithm] = :gpgme
51
+ options[:file] = '/path/to/data.txt'
52
+ options[:pw] = File.read('/path/to/password.txt')
53
+ RapidVaults::API.main(options)
54
+ end
55
+
56
+ # returns decrypted_contents
57
+ def gpg_decrypt
58
+ ENV['GNUPGHOME'] = '/home/chris/.gnupg'
59
+
60
+ options = {}
61
+ options[:action] = :decrypt
62
+ options[:algorithm] = :gpgme
63
+ options[:file] = '/path/to/encrypted_data.txt'
64
+ options[:pw] = File.read('/path/to/password.txt')
65
+ RapidVaults::API.main(options)
66
+ end
@@ -0,0 +1,28 @@
1
+ # mymodule/lib/puppet/functions/gpg_decrypt.rb
2
+ Puppet::Functions.create_function(:'gpg_decrypt') do
3
+ # Decrypts a file with GnuPG.
4
+ # @param [String] file The file to decrypt.
5
+ # @param [String] gpghome The path to the GnuPG home directory containing the credentials.
6
+ # @param [String] password_file The password file to use for decryption.
7
+ # @return [String] Returns a string of decrypted contents.
8
+ # @example Decrypting a file.
9
+ # gpg_encrypt('/path/to/encrypted_data.txt', '/home/alice/.gnupg', '/path/to/password.txt') => 'decrypted'
10
+ dispatch :gpg_decrypt do
11
+ required_param 'String', :file
12
+ required_param 'String', :gpghome
13
+ required_param 'String', :password_file
14
+ return_type 'String'
15
+ end
16
+
17
+ def gpg_decrypt(file, gpghome, password_file)
18
+ begin
19
+ require 'rapid-vaults'
20
+ rescue LoadError
21
+ raise 'Rapid Vaults is required to be installed on the puppet master to use this custom function!'
22
+ end
23
+
24
+ ENV['GNUPGHOME'] = gpghome
25
+
26
+ RapidVaults::API.main(action: :decrypt, algorithm: :gpgme, file: file, pw: password_file)
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ # mymodule/lib/puppet/functions/gpg_encrypt.rb
2
+ Puppet::Functions.create_function(:'gpg_encrypt') do
3
+ # Encrypts a file with GnuPG.
4
+ # @param [String] file The file to encrypt.
5
+ # @param [String] gpghome The path to the GnuPG home directory containing the credentials.
6
+ # @param [String] password_file The password file to use for encryption.
7
+ # @return [String] Returns a string of encrypted contents.
8
+ # @example Encrypting a file.
9
+ # gpg_encrypt('/path/to/data.txt', '/home/alice/.gnupg', '/path/to/password.txt') => 'asdnlfi378rth43rt78h4t8b3v844b'
10
+ dispatch :gpg_encrypt do
11
+ required_param 'String', :file
12
+ required_param 'String', :gpghome
13
+ required_param 'String', :password_file
14
+ return_type 'String'
15
+ end
16
+
17
+ def gpg_encrypt(file, gpghome, password_file)
18
+ begin
19
+ require 'rapid-vaults'
20
+ rescue LoadError
21
+ raise 'Rapid Vaults is required to be installed on the puppet master to use this custom function!'
22
+ end
23
+
24
+ ENV['GNUPGHOME'] = gpghome
25
+
26
+ RapidVaults::API.main(action: :encrypt, algorithm: :gpgme, file: file, pw: password_file)
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ # mymodule/lib/puppet/functions/ssl_decrypt.rb
2
+ Puppet::Functions.create_function(:'ssl_decrypt') do
3
+ # Decrypts a file with OpenSSL.
4
+ # @param [String] file The file to decrypt.
5
+ # @param [String] key The key file to use for decryption.
6
+ # @param [String] nonce The nonce file to use for decryption.
7
+ # @param [String] tag The tag file to use for decryption.
8
+ # @param [String] password_file The optional password file to use for decryption.
9
+ # @return [String] Returns a string of decrypted contents.
10
+ # @example Decrypting a file.
11
+ # ssl_decrypt('/path/to/encrypted_data.txt', '/path/to/cert.key', '/path/to/nonce.txt', '/path/to/tag.txt', '/path/to/password.txt') => 'decrypted'
12
+ dispatch :ssl_decrypt do
13
+ required_param 'String', :file
14
+ required_param 'String', :key
15
+ required_param 'String', :nonce
16
+ required_param 'String', :tag
17
+ optional_param 'String', :password_file
18
+ return_type 'String'
19
+ end
20
+
21
+ def ssl_decrypt(file, key, nonce, tag, password_file = nil)
22
+ begin
23
+ require 'rapid-vaults'
24
+ rescue LoadError
25
+ raise 'Rapid Vaults is required to be installed on the puppet master to use this custom function!'
26
+ end
27
+
28
+ if password_file.nil?
29
+ RapidVaults::API.main(action: :decrypt, file: file, key: key, nonce: nonce, tag: tag)
30
+ else
31
+ RapidVaults::API.main(action: :encrypt, file: file, key: key, nonce: nonce, tag: tag, pw: File.read(password_file))
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ # mymodule/lib/puppet/functions/ssl_encrypt.rb
2
+ Puppet::Functions.create_function(:'ssl_encrypt') do
3
+ # Encrypts a file with OpenSSL.
4
+ # @param [String] file The file to encrypt.
5
+ # @param [String] key The key file to use for encryption.
6
+ # @param [String] nonce The nonce file to use for encryption.
7
+ # @param [String] password_file The optional password file to use for encryption.
8
+ # @return [Hash] Returns a hash. First key-value is the encrypted contents and the second is the tag.
9
+ # @example Encrypting a file.
10
+ # ssl_encrypt('/path/to/data.txt', '/path/to/cert.key', '/path/to/nonce.txt', '/path/to/password.txt') => { encrypted_contents => 'asdfnlm34kl5m3lasdf34324fdnfsd', tag => 'fwr32r2ewf' }
11
+ dispatch :ssl_encrypt do
12
+ required_param 'String', :file
13
+ required_param 'String', :key
14
+ required_param 'String', :nonce
15
+ optional_param 'String', :password_file
16
+ return_type 'Hash'
17
+ end
18
+
19
+ def ssl_encrypt(file, key, nonce, password_file = nil)
20
+ begin
21
+ require 'rapid-vaults'
22
+ rescue LoadError
23
+ raise 'Rapid Vaults is required to be installed on the puppet master to use this custom function!'
24
+ end
25
+
26
+ hash = {}
27
+ if password_file.nil?
28
+ hash[:encrypted_contents], hash[:tag] = RapidVaults::API.main(action: :encrypt, file: file, key: key, nonce: nonce)
29
+ else
30
+ hash[:encrypted_contents], hash[:tag] = RapidVaults::API.main(action: :encrypt, file: file, key: key, nonce: nonce, pw: File.read(password_file))
31
+ end
32
+ hash
33
+ end
34
+ end
@@ -4,13 +4,13 @@ require_relative '../../lib/rapid-vaults/api'
4
4
  describe RapidVaults::API do
5
5
  context '.parse' do
6
6
  it 'correctly parses the settings for encrypt' do
7
- expect(RapidVaults::API.parse(action: :encrypt, file: 'file.txt', key: 'key.txt', nonce: 'nonce.txt', pw: 'secret')).to eq(algorithm: :openssl, ui: :api, action: :encrypt, file: 'file.txt', key: 'key.txt', nonce: 'nonce.txt', pw: 'secret')
7
+ expect(RapidVaults::API.parse(action: :encrypt, file: 'file.txt', key: 'key.txt', nonce: 'nonce.txt', pw: 'secret')).to eq(ui: :api, action: :encrypt, file: 'file.txt', key: 'key.txt', nonce: 'nonce.txt', pw: 'secret')
8
8
  end
9
9
  it 'correctly parses the settings for decrypt' do
10
- expect(RapidVaults::API.parse(action: :decrypt, file: 'file.txt', key: 'key.txt', nonce: 'nonce.txt', tag: 'tag.txt', pw: 'secret')).to eq(algorithm: :openssl, ui: :api, action: :decrypt, file: 'file.txt', key: 'key.txt', nonce: 'nonce.txt', tag: 'tag.txt', pw: 'secret')
10
+ expect(RapidVaults::API.parse(action: :decrypt, file: 'file.txt', key: 'key.txt', nonce: 'nonce.txt', tag: 'tag.txt', pw: 'secret')).to eq(ui: :api, action: :decrypt, file: 'file.txt', key: 'key.txt', nonce: 'nonce.txt', tag: 'tag.txt', pw: 'secret')
11
11
  end
12
12
  it 'correctly parses the settings for generate' do
13
- expect(RapidVaults::API.parse(action: :generate)).to eq(algorithm: :openssl, ui: :api, action: :generate)
13
+ expect(RapidVaults::API.parse(action: :generate)).to eq(ui: :api, action: :generate)
14
14
  end
15
15
  it 'correctly overrides the algorithm setting' do
16
16
  expect(RapidVaults::API.parse(algorithm: :gpgme)).to eq(algorithm: :gpgme, ui: :api)
@@ -7,16 +7,19 @@ describe RapidVaults::CLI do
7
7
  expect(RapidVaults::CLI.parse(%w[--gpg])).to eq(algorithm: :gpgme, ui: :cli)
8
8
  end
9
9
  it 'correctly parses the user arguments for encrypt' do
10
- expect(RapidVaults::CLI.parse(%w[-e -k key.txt -n nonce.txt -p secret file.txt])).to eq(algorithm: :openssl, ui: :cli, action: :encrypt, key: 'key.txt', nonce: 'nonce.txt', pw: 'secret')
10
+ expect(RapidVaults::CLI.parse(%w[-e -k key.txt -n nonce.txt -p secret file.txt])).to eq(ui: :cli, action: :encrypt, key: 'key.txt', nonce: 'nonce.txt', pw: 'secret')
11
11
  end
12
12
  it 'correctly parses the arguments for decrypt' do
13
- expect(RapidVaults::CLI.parse(%w[-d -k key.txt -n nonce.txt -t tag.txt -p secret file.txt])).to eq(algorithm: :openssl, ui: :cli, action: :decrypt, key: 'key.txt', nonce: 'nonce.txt', tag: 'tag.txt', pw: 'secret')
13
+ expect(RapidVaults::CLI.parse(%w[-d -k key.txt -n nonce.txt -t tag.txt -p secret file.txt])).to eq(ui: :cli, action: :decrypt, key: 'key.txt', nonce: 'nonce.txt', tag: 'tag.txt', pw: 'secret')
14
14
  end
15
15
  it 'correctly parses the arguments for openssl generate' do
16
- expect(RapidVaults::CLI.parse(%w[-g])).to eq(algorithm: :openssl, ui: :cli, action: :generate)
16
+ expect(RapidVaults::CLI.parse(%w[-g -o /home/bob])).to eq(ui: :cli, action: :generate, outdir: '/home/bob')
17
17
  end
18
18
  it 'correctly parses the arguments for gpg generate' do
19
19
  expect(RapidVaults::CLI.parse(%W[--gpg -g --gpgparams #{fixtures_dir}/file.yaml])).to eq(algorithm: :gpgme, ui: :cli, action: :generate, gpgparams: "foo: bar\n")
20
20
  end
21
+ it 'correctly parses the arguments for puppet integrations' do
22
+ expect(RapidVaults::CLI.parse(%w[--puppet -o /dir])).to eq(ui: :cli, action: :integrate, integrate: :puppet, outdir: '/dir')
23
+ end
21
24
  end
22
25
  end
@@ -3,15 +3,15 @@ require_relative '../../lib/rapid-vaults/encrypt'
3
3
  require_relative '../../lib/rapid-vaults/decrypt'
4
4
 
5
5
  describe Decrypt do
6
- after(:all) do
7
- %w[tag.txt encrypted.txt decrypted.txt].each { |file| File.delete(file) }
8
- end
9
-
10
6
  context '.openssl' do
11
7
  before(:all) do
12
8
  Encrypt.openssl(ui: :cli, file: "foo: bar\n", key: '���b+����R�v�Í%("����=8o/���', nonce: 'Ëá!í^Uë^EÜ<83>oã^M')
13
9
  end
14
10
 
11
+ after(:all) do
12
+ %w[tag.txt encrypted.txt decrypted.txt].each { |file| File.delete(file) }
13
+ end
14
+
15
15
  it 'outputs a decrypted file with the key, nonce, and tag from the cli' do
16
16
  Decrypt.openssl(ui: :cli, file: File.read('encrypted.txt'), key: '���b+����R�v�Í%("����=8o/���', nonce: 'Ëá!í^Uë^EÜ<83>oã^M', tag: File.read('tag.txt'))
17
17
  expect(File.file?('decrypted.txt')).to be true
@@ -34,6 +34,10 @@ describe Decrypt do
34
34
  Encrypt.gpgme(ui: :cli, file: "foo: bar\n", key: '', pw: 'foo')
35
35
  end
36
36
 
37
+ after(:all) do
38
+ %w[encrypted.txt decrypted.txt].each { |file| File.delete(file) }
39
+ end
40
+
37
41
  it 'outputs a decrypted file with the key from the cli' do
38
42
  Decrypt.gpgme(ui: :cli, file: File.read('encrypted.txt'), key: '', pw: 'foo')
39
43
  expect(File.file?('decrypted.txt')).to be true
@@ -2,11 +2,11 @@ require_relative '../spec_helper'
2
2
  require_relative '../../lib/rapid-vaults/encrypt'
3
3
 
4
4
  describe Encrypt do
5
- after(:all) do
6
- %w[tag.txt encrypted.txt].each { |file| File.delete(file) }
7
- end
8
-
9
5
  context '.openssl' do
6
+ after(:all) do
7
+ %w[tag.txt encrypted.txt].each { |file| File.delete(file) }
8
+ end
9
+
10
10
  it 'outputs an encrypted file with the key and nonce from the cli' do
11
11
  Encrypt.openssl(ui: :cli, file: "foo: bar\n", key: '���b+����R�v�Í%("����=8o/���', nonce: 'Ëá!í^Uë^EÜ<83>oã^M')
12
12
  expect(File.file?('tag.txt')).to be true
@@ -25,7 +25,7 @@ describe Generate do
25
25
 
26
26
  context '.gpgme' do
27
27
  it 'raises an error for a missing GNUPGHOME variable' do
28
- expect { Generate.gpgme(gpgparams: File.read("#{fixtures_dir}/gpgparams.txt")) }.to raise_error('Environment variable GNUPGHOME was not set.')
28
+ expect { Generate.gpgme(gpgparams: File.read("#{fixtures_dir}/gpgparams.txt")) }.to raise_error('Environment variable "GNUPGHOME" was not set.')
29
29
  end
30
30
  # travis ci cannot support non-interactive gpg
31
31
  unless File.directory?('/home/travis')
@@ -0,0 +1,28 @@
1
+ require_relative '../spec_helper'
2
+ require_relative '../../lib/rapid-vaults/integration'
3
+
4
+ describe Integration do
5
+ context '.puppet' do
6
+ after(:all) do
7
+ %w[puppet_gpg_decrypt.rb puppet_gpg_encrypt.rb puppet_ssl_decrypt.rb puppet_ssl_encrypt.rb].each { |file| File.delete(file) }
8
+ end
9
+
10
+ it 'outputs the puppet integrations to the specified directory' do
11
+ Integration.puppet({})
12
+ %w[puppet_gpg_decrypt.rb puppet_gpg_encrypt.rb puppet_ssl_decrypt.rb puppet_ssl_encrypt.rb].each do |file|
13
+ expect(File.file?(file)).to be true
14
+ end
15
+ end
16
+ end
17
+
18
+ context '.chef' do
19
+ after(:all) do
20
+ File.delete('chef.rb')
21
+ end
22
+
23
+ it 'outputs the chef integrations to the specified directory' do
24
+ Integration.chef({})
25
+ expect(File.file?('chef.rb')).to be true
26
+ end
27
+ end
28
+ end
@@ -3,20 +3,23 @@ require_relative '../lib/rapid-vaults'
3
3
 
4
4
  describe RapidVaults do
5
5
  context '.process' do
6
+ it 'raises an error for a nonexistent output directory' do
7
+ expect { RapidVaults.process(outdir: '/foo/bar/baz') }.to raise_error('The output directory /foo/bar/baz does not exist or is not a directory!')
8
+ end
6
9
  it 'raises an error for a non-string password with openssl' do
7
- expect { RapidVaults.process(algorithm: :openssl, action: :encrypt, file: 'a', key: 'b', nonce: 'c', pw: 1) }.to raise_error('Password must be a string.')
10
+ expect { RapidVaults.process(action: :encrypt, file: 'a', key: 'b', nonce: 'c', pw: 1) }.to raise_error('Password must be a string.')
8
11
  end
9
12
  it 'raises an error for a missing argument to encrypt with openssl' do
10
- expect { RapidVaults.process(algorithm: :openssl, action: :encrypt, file: 'a', key: 'b') }.to raise_error('File, key, and nonce arguments are required for encryption.')
13
+ expect { RapidVaults.process(action: :encrypt, file: 'a', key: 'b') }.to raise_error('File, key, and nonce arguments are required for encryption.')
11
14
  end
12
15
  it 'raises an error for a missing argument to decrypt with openssl' do
13
- expect { RapidVaults.process(algorithm: :openssl, action: :decrypt, file: 'a', key: 'b', nonce: 'c') }.to raise_error('File, key, nonce, and tag arguments are required for decryption.')
16
+ expect { RapidVaults.process(action: :decrypt, file: 'a', key: 'b', nonce: 'c') }.to raise_error('File, key, nonce, and tag arguments are required for decryption.')
14
17
  end
15
18
  it 'raises an error for a missing argument to decrypt with gpgme' do
16
19
  expect { RapidVaults.process(algorithm: :gpgme, action: :decrypt, file: 'a') }.to raise_error('File and password arguments required for encryption or decryption.')
17
20
  end
18
21
  it 'raises an error for a missing action with openssl' do
19
- expect { RapidVaults.process(algorithm: :openssl, file: 'a', key: 'b', nonce: 'c', tag: 'd') }.to raise_error('Action must be one of generate, encrypt, or decrypt.')
22
+ expect { RapidVaults.process(file: 'a', key: 'b', nonce: 'c', tag: 'd') }.to raise_error('Action must be one of generate, encrypt, or decrypt.')
20
23
  end
21
24
  it 'raises an error for a missing action with gpgme' do
22
25
  expect { RapidVaults.process(algorithm: :gpgme, file: 'a', key: 'b') }.to raise_error('Action must be one of generate, encrypt, or decrypt.')
@@ -25,11 +28,15 @@ describe RapidVaults do
25
28
  expect { RapidVaults.process(algorithm: :gpgme, action: :generate) }.to raise_error('GPG params file argument required for generation.')
26
29
  end
27
30
  it 'raises an error for a nonexistent input file' do
28
- expect { RapidVaults.process(algorithm: :openssl, action: :encrypt, file: 'a', key: 'b', nonce: 'c', tag: 'd') }.to raise_error('Input file is not an existing file.')
31
+ expect { RapidVaults.process(action: :encrypt, file: 'a', key: 'b', nonce: 'c', tag: 'd') }.to raise_error('Input file is not an existing file.')
32
+ end
33
+ it 'reads in all input files correctly for openssl encryption' do
34
+ dummy = fixtures_dir + 'file.yaml'
35
+ expect { RapidVaults.process(action: :encrypt, file: dummy, key: dummy, nonce: dummy, pw: 'password') }.not_to raise_exception
29
36
  end
30
- it 'reads in all input files correctly for decryption' do
37
+ it 'reads in all input files correctly for gpgme decryption' do
31
38
  dummy = fixtures_dir + 'file.yaml'
32
- expect { RapidVaults.process(algorithm: :openssl, action: :encrypt, file: dummy, key: dummy, nonce: dummy, pw: 'password') }.not_to raise_exception
39
+ expect { RapidVaults.process(algorithm: :gpgme, action: :decrypt, file: dummy, pw: 'password') }.not_to raise_exception
33
40
  end
34
41
  end
35
42
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rapid-vaults
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Schuchard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-18 00:00:00.000000000 Z
11
+ date: 2018-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gpgme
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.0.0
19
+ version: '2.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.0.0
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -102,6 +102,12 @@ files:
102
102
  - lib/rapid-vaults/decrypt.rb
103
103
  - lib/rapid-vaults/encrypt.rb
104
104
  - lib/rapid-vaults/generate.rb
105
+ - lib/rapid-vaults/integration.rb
106
+ - lib/rapid-vaults/integrations/chef.rb
107
+ - lib/rapid-vaults/integrations/puppet_gpg_decrypt.rb
108
+ - lib/rapid-vaults/integrations/puppet_gpg_encrypt.rb
109
+ - lib/rapid-vaults/integrations/puppet_ssl_decrypt.rb
110
+ - lib/rapid-vaults/integrations/puppet_ssl_encrypt.rb
105
111
  - spec/fixtures/file.yaml
106
112
  - spec/fixtures/gpgparams.txt
107
113
  - spec/rapid-vaults/api_spec.rb
@@ -109,6 +115,7 @@ files:
109
115
  - spec/rapid-vaults/decrypt_spec.rb
110
116
  - spec/rapid-vaults/encrypt_spec.rb
111
117
  - spec/rapid-vaults/generate_spec.rb
118
+ - spec/rapid-vaults/integration_spec.rb
112
119
  - spec/rapid-vaults_spec.rb
113
120
  - spec/spec_helper.rb
114
121
  - spec/system/system_spec.rb
@@ -144,6 +151,7 @@ test_files:
144
151
  - spec/rapid-vaults/decrypt_spec.rb
145
152
  - spec/rapid-vaults/encrypt_spec.rb
146
153
  - spec/rapid-vaults/generate_spec.rb
154
+ - spec/rapid-vaults/integration_spec.rb
147
155
  - spec/rapid-vaults_spec.rb
148
156
  - spec/spec_helper.rb
149
157
  - spec/system/system_spec.rb