crypt_keeper 1.1.1 → 2.0.0.rc1

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: 78d7a7f1ea679f9a1542a65b537a446065c9cd27
4
- data.tar.gz: 518d78e7d4a80e07faa80b9eac9c3b268e2db2c8
3
+ metadata.gz: 177d3771b01336174fdcc4db5f237335f8f206cd
4
+ data.tar.gz: 5f0f53fd0e3fcae45bae65fa63276067e651682c
5
5
  SHA512:
6
- metadata.gz: 30b9ccbea99c9ac89ee4bf4c9df73fc0b95e2ae3f65aca3e9936a95bd406d271e672e73cefa2c717a2f0c057c638ca876a238c7058da2c3ad6e3f2d2d12720cb
7
- data.tar.gz: 07f33f2caca79c5be2c45f2365601e8939b5c64200fba53c00de3e70a9d6b221a68efe47aad00fc7b42003bce2c964ce68701656966149afe4b65dfc45a4e0a7
6
+ metadata.gz: cbce4c1e8e9665441bc3660542eb83c34efb66894ed0be3888ab03860831067a6d275bef837df62636278056524c4aae2522ef26479502815f3a5313c42fa9d1
7
+ data.tar.gz: 81429db29edfea6bdcfd6934926dec0c3f84e79268017d056c9351fcbeeaf00f2f29a5506f3100cd428321e438fda081c72d5ced47b88229d84a8ff860102999
@@ -1,19 +1,15 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 2.1.10
5
- - 2.2.5
6
- - 2.3.1
4
+ - 2.2.7
5
+ - 2.3.4
6
+ - 2.4.1
7
7
 
8
8
  gemfile:
9
9
  - gemfiles/activerecord_4_2.gemfile
10
+ - gemfiles/activerecord_5_0.gemfile
10
11
  - gemfiles/activerecord_5_1.gemfile
11
12
 
12
- matrix:
13
- exclude:
14
- - gemfile: gemfiles/activerecord_5_1.gemfile
15
- rvm: 2.1.10
16
-
17
13
  addons:
18
14
  postgresql: 9.3
19
15
 
data/Appraisals CHANGED
@@ -7,3 +7,8 @@ appraise "activerecord_5_0" do
7
7
  gem "activerecord", "~> 5.0.0"
8
8
  gem "activesupport", "~> 5.0.0"
9
9
  end
10
+
11
+ appraise "activerecord_5_1" do
12
+ gem "activerecord", "~> 5.1.0"
13
+ gem "activesupport", "~> 5.1.0"
14
+ end
data/README.md CHANGED
@@ -15,7 +15,7 @@ is a simple class that does 3 things.
15
15
  Note: Any options defined using `crypt_keeper` will be passed to `new` as a
16
16
  hash.
17
17
 
18
- You can see an AES example [here](https://github.com/jmazzi/crypt_keeper/blob/master/lib/crypt_keeper/provider/aes_new.rb).
18
+ You can see an example [here](https://github.com/jmazzi/crypt_keeper/blob/master/lib/crypt_keeper/provider/active_support.rb).
19
19
 
20
20
  ## Why?
21
21
 
@@ -27,7 +27,7 @@ simple that *just works*.
27
27
 
28
28
  ```ruby
29
29
  class MyModel < ActiveRecord::Base
30
- crypt_keeper :field, :other_field, :encryptor => :aes_new, :key => 'super_good_password', salt: 'salt'
30
+ crypt_keeper :field, :other_field, encryptor: :active_support, key: 'super_good_password', salt: 'salt'
31
31
  end
32
32
 
33
33
  model = MyModel.new(field: 'sometext')
@@ -53,7 +53,7 @@ You can force an encoding on the plaintext before encryption and after decryptio
53
53
 
54
54
  ```ruby
55
55
  class MyModel < ActiveRecord::Base
56
- crypt_keeper :field, :other_field, :encryptor => :aes_new, :key => 'super_good_password', salt: 'salt', :encoding => 'UTF-8'
56
+ crypt_keeper :field, :other_field, encryptor: :active_support, key: 'super_good_password', salt: 'salt', encoding: 'UTF-8'
57
57
  end
58
58
 
59
59
  model = MyModel.new(field: 'Tromsø')
@@ -68,7 +68,7 @@ If you are working with an existing table you would like to encrypt, you must us
68
68
 
69
69
  ```ruby
70
70
  class MyExistingModel < ActiveRecord::Base
71
- crypt_keeper :field, :other_field, :encryptor => :aes_new, :key => 'super_good_password', salt: 'salt'
71
+ crypt_keeper :field, :other_field, encryptor: :active_support, key: 'super_good_password', salt: 'salt'
72
72
  end
73
73
 
74
74
  MyExistingModel.encrypt_table!
@@ -78,10 +78,10 @@ Running `encrypt_table!` will encrypt all rows in the database using the encrypt
78
78
 
79
79
  ## Supported Available Encryptors
80
80
 
81
- There are four supported encryptors: `aes_new`, `mysql_aes_new`, `postgres_pgp`, `postgres_pgp_public_key`.
81
+ There are four supported encryptors: `active_support`, `mysql_aes_new`, `postgres_pgp`, `postgres_pgp_public_key`.
82
82
 
83
- * [AES New](https://github.com/jmazzi/crypt_keeper/blob/master/lib/crypt_keeper/provider/aes_new.rb)
84
- * Encryption is peformed using AES-256 via OpenSSL.
83
+ * [ActiveSupport](https://github.com/jmazzi/crypt_keeper/blob/master/lib/crypt_keeper/provider/active_support.rb)
84
+ * Encryption is performed using [ActiveSupport::MessageEncryptor](http://api.rubyonrails.org/classes/ActiveSupport/MessageEncryptor.html)
85
85
  * Passphrases are derived using [PBKDF2](http://en.wikipedia.org/wiki/PBKDF2)
86
86
 
87
87
  * [MySQL AES New](https://github.com/jmazzi/crypt_keeper/blob/master/lib/crypt_keeper/provider/mysql_aes_new.rb)
@@ -111,8 +111,8 @@ There are four supported encryptors: `aes_new`, `mysql_aes_new`, `postgres_pgp`,
111
111
  ## Searching
112
112
  Searching ciphertext is a complex problem that varies depending on the encryption algorithm you choose. All of the bundled providers include search support, but they have some caveats.
113
113
 
114
- * AES
115
- * The Ruby implementation of AES uses a random initialization vector. The same plaintext encrypted multiple times will have different output each time for the ciphertext. Since this is the case, it is not possible to search leveraging the database. Database rows will need to be filtered in memory. It is suggested that you use a scope or ActiveRecord batches to narrow the results before seaching them.
114
+ * ActiveSupport::MessageEncryptor
115
+ * ActiveSupport's MessageEncryptor uses a random initialization vector when generating keys. The same plaintext encrypted multiple times will have different output each time for the ciphertext. Since this is the case, it is not possible to search leveraging the database. Database rows will need to be filtered in memory. It is suggested that you use a scope or ActiveRecord batches to narrow the results before seaching them.
116
116
 
117
117
  * Mysql AES
118
118
  * Surprisingly, MySQL's implementation of AES does not use a random initialization vector. The column containing the ciphertext can be indexed and searched quickly.
@@ -157,10 +157,35 @@ as a string or an underscored symbol
157
157
 
158
158
  ```ruby
159
159
  class MyModel < ActiveRecord::Base
160
- crypt_keeper :field, :other_field, :encryptor => :my_encryptor, :key => 'super_good_password'
160
+ crypt_keeper :field, :other_field, encryptor: :my_encryptor, key: 'super_good_password'
161
161
  end
162
162
  ```
163
163
 
164
+ ## Migrating from CryptKeeper 1.x to 2.0
165
+
166
+ CryptKeeper 2.0 removes the AES encryptor due to security issues in the
167
+ underlying AES gem. If you were previously using the `aes_new` encryptor, you
168
+ will need to follow these instructions to reencrypt your data.
169
+
170
+ The general migration path is as follows:
171
+
172
+ 1. Enable maintenance mode in any live apps
173
+ 2. Backup database
174
+ 3. Decrypt tables: TableName.decrypt_table!
175
+ 4. Update to 2.0.0.rc1 in your app. Update the encryptor to use :active_support
176
+ 5. Encrypt tables: `TableName.encrypt_table!`
177
+ 6. Verify data can be decrypted: `TableName.first`
178
+ 7. Disable maintenance mode if necessary
179
+
180
+ In case you experience problems, the rollback procedure is as follows:
181
+
182
+ 1. Enable maintenance mode
183
+ 2. Backup database again
184
+ 3. Restore first database dump, from before CryptKeeper 2.0.0.rc1
185
+ 4. Verify data can be decrypted
186
+ 5. Disable maintenance mode
187
+ 6. Let us know what happened :(
188
+
164
189
  ## Requirements
165
190
 
166
191
  CryptKeeper has been tested against ActiveRecord 4.2 and 5.0 using Ruby
@@ -16,9 +16,10 @@ Gem::Specification.new do |gem|
16
16
  gem.require_paths = ["lib"]
17
17
  gem.version = CryptKeeper::VERSION
18
18
 
19
+ gem.post_install_message = "WARNING: CryptKeeper 2.0 contains breaking changes and may require you to reencrypt your data! Please view the README at https://github.com/jmazzi/crypt_keeper for more information."
20
+
19
21
  gem.add_runtime_dependency 'activerecord', '>= 4.2', '< 5.2'
20
22
  gem.add_runtime_dependency 'activesupport', '>= 4.2', '< 5.2'
21
- gem.add_runtime_dependency 'aes', '~> 0.5.0'
22
23
  gem.add_runtime_dependency 'armor', '~> 0.0.2'
23
24
 
24
25
  gem.add_development_dependency 'rspec', '~> 3.5.0'
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 5.0.0"
6
+ gem "activesupport", "~> 5.0.0"
7
+
8
+ gemspec :path => "../"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "~> 5.1"
6
- gem "activesupport", "~> 5.1"
5
+ gem "activerecord", "~> 5.1.0"
6
+ gem "activesupport", "~> 5.1.0"
7
7
 
8
8
  gemspec :path => "../"
@@ -4,7 +4,7 @@ require 'crypt_keeper/version'
4
4
  require 'crypt_keeper/model'
5
5
  require 'crypt_keeper/helper'
6
6
  require 'crypt_keeper/provider/base'
7
- require 'crypt_keeper/provider/aes_new'
7
+ require 'crypt_keeper/provider/active_support'
8
8
  require 'crypt_keeper/provider/mysql_aes_new'
9
9
  require 'crypt_keeper/provider/postgres_base'
10
10
  require 'crypt_keeper/provider/postgres_pgp'
@@ -40,6 +40,7 @@ module CryptKeeper
40
40
 
41
41
  module DigestPassphrase
42
42
  def digest_passphrase(key, salt)
43
+ require "armor"
43
44
  raise ArgumentError.new("Missing :key") if key.blank?
44
45
  raise ArgumentError.new("Missing :salt") if salt.blank?
45
46
  ::Armor.digest(key, salt)
@@ -3,7 +3,7 @@ require 'active_support/core_ext/array/extract_options'
3
3
 
4
4
  module CryptKeeper
5
5
  module Model
6
- extend ActiveSupport::Concern
6
+ extend ::ActiveSupport::Concern
7
7
 
8
8
  # Public: Ensures that each field exist and is of type text. This prevents
9
9
  # encrypted data from being truncated.
@@ -0,0 +1,51 @@
1
+ require "active_support/message_encryptor"
2
+
3
+ module CryptKeeper
4
+ module Provider
5
+ class ActiveSupport < Base
6
+ attr_reader :encryptor
7
+
8
+ # Public: Initializes the encryptor
9
+ #
10
+ # options - A hash, :key and :salt are required
11
+ #
12
+ # Returns nothing.
13
+ def initialize(options = {})
14
+ key = options.fetch(:key)
15
+ salt = options.fetch(:salt)
16
+
17
+ @encryptor = ::ActiveSupport::MessageEncryptor.new \
18
+ ::ActiveSupport::KeyGenerator.new(key).generate_key(salt, 32)
19
+ end
20
+
21
+ # Public: Encrypts a string
22
+ #
23
+ # value - Plaintext value
24
+ #
25
+ # Returns an encrypted string
26
+ def encrypt(value)
27
+ encryptor.encrypt_and_sign(value)
28
+ end
29
+
30
+ # Public: Decrypts a string
31
+ #
32
+ # value - Cipher text
33
+ #
34
+ # Returns a plaintext string
35
+ def decrypt(value)
36
+ encryptor.decrypt_and_verify(value)
37
+ end
38
+
39
+ # Public: Searches the table
40
+ #
41
+ # records - ActiveRecord::Relation
42
+ # field - Field name to match
43
+ # criteria - Value to match
44
+ #
45
+ # Returns an Enumerable
46
+ def search(records, field, criteria)
47
+ records.select { |record| record[field] == criteria }
48
+ end
49
+ end
50
+ end
51
+ end
@@ -12,7 +12,7 @@ module CryptKeeper
12
12
  #
13
13
  # options - A hash, :key and :salt are required
14
14
  def initialize(options = {})
15
- ActiveSupport.run_load_hooks(:crypt_keeper_mysql_aes_log, self)
15
+ ::ActiveSupport.run_load_hooks(:crypt_keeper_mysql_aes_log, self)
16
16
  @key = digest_passphrase(options[:key], options[:salt])
17
17
  end
18
18
 
@@ -8,7 +8,7 @@ module CryptKeeper
8
8
  #
9
9
  # options - A hash, :key is required
10
10
  def initialize(options = {})
11
- ActiveSupport.run_load_hooks(:crypt_keeper_postgres_pgp_log, self)
11
+ ::ActiveSupport.run_load_hooks(:crypt_keeper_postgres_pgp_log, self)
12
12
 
13
13
  @key = options.fetch(:key) do
14
14
  raise ArgumentError, "Missing :key"
@@ -4,7 +4,7 @@ module CryptKeeper
4
4
  attr_accessor :key
5
5
 
6
6
  def initialize(options = {})
7
- ActiveSupport.run_load_hooks(:crypt_keeper_postgres_pgp_log, self)
7
+ ::ActiveSupport.run_load_hooks(:crypt_keeper_postgres_pgp_log, self)
8
8
 
9
9
  @key = options.fetch(:key) do
10
10
  raise ArgumentError, "Missing :key"
@@ -1,3 +1,3 @@
1
1
  module CryptKeeper
2
- VERSION = "1.1.1"
2
+ VERSION = "2.0.0.rc1"
3
3
  end
@@ -120,7 +120,7 @@ describe CryptKeeper::Model do
120
120
  end
121
121
 
122
122
  context "Encodings" do
123
- subject { create_encrypted_model :storage, key: 'tool', salt: 'salt', encryptor: :aes_new, encoding: 'utf-8' }
123
+ subject { create_encrypted_model :storage, key: 'tool', salt: 'salt', encryptor: :active_support, encoding: 'utf-8' }
124
124
 
125
125
  it "forces the encoding on decrypt" do
126
126
  record = subject.create!(storage: 'Tromsø')
@@ -137,7 +137,7 @@ describe CryptKeeper::Model do
137
137
  end
138
138
 
139
139
  context "Initial Table Encryption" do
140
- subject { create_encrypted_model :storage, key: 'tool', salt: 'salt', encryptor: :aes_new }
140
+ subject { create_encrypted_model :storage, key: 'tool', salt: 'salt', encryptor: :active_support }
141
141
 
142
142
  before do
143
143
  subject.delete_all
@@ -146,14 +146,14 @@ describe CryptKeeper::Model do
146
146
  end
147
147
 
148
148
  it "encrypts the table" do
149
- expect { subject.first(5).map(&:storage) }.to raise_error(OpenSSL::Cipher::CipherError)
149
+ expect { subject.first(5).map(&:storage) }.to raise_error(ActiveSupport::MessageVerifier::InvalidSignature)
150
150
  subject.encrypt_table!
151
151
  expect { subject.first(5).map(&:storage) }.not_to raise_error
152
152
  end
153
153
  end
154
154
 
155
155
  context "Table Decryption (Reverse of Initial Table Encryption)" do
156
- subject { create_encrypted_model :storage, key: 'tool', salt: 'salt', encryptor: :aes_new }
156
+ subject { create_encrypted_model :storage, key: 'tool', salt: 'salt', encryptor: :active_support }
157
157
  let!(:storage_entries) { 5.times.map { |i| "testing#{i}" } }
158
158
 
159
159
  before do
@@ -168,7 +168,7 @@ describe CryptKeeper::Model do
168
168
  end
169
169
 
170
170
  context "Missing Attributes" do
171
- subject { create_encrypted_model :storage, key: 'tool', salt: 'salt', encryptor: :aes_new, encoding: 'utf-8' }
171
+ subject { create_encrypted_model :storage, key: 'tool', salt: 'salt', encryptor: :active_support, encoding: 'utf-8' }
172
172
 
173
173
  it "doesn't attempt decryption of missing attributes" do
174
174
  subject.create!(storage: 'blah')
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe CryptKeeper::Provider::ActiveSupport do
4
+ subject { described_class.new(key: 'cake', salt: 'salt') }
5
+
6
+ let :plaintext do
7
+ "string"
8
+ end
9
+
10
+ let :encrypted do
11
+ subject.encrypt plaintext
12
+ end
13
+
14
+ let :decrypted do
15
+ subject.decrypt encrypted
16
+ end
17
+
18
+ describe "#encrypt" do
19
+ specify { expect(encrypted).to_not eq(plaintext) }
20
+ specify { expect(encrypted).to_not be_blank }
21
+ end
22
+
23
+ describe "#decrypt" do
24
+ specify { expect(decrypted).to eq(plaintext) }
25
+ specify { expect(decrypted).to_not be_blank }
26
+ end
27
+
28
+ describe "#search" do
29
+ let :records do
30
+ [{ name: 'Bob' }, { name: 'Tim' }]
31
+ end
32
+
33
+ it "finds the matching record" do
34
+ expect(subject.search(records, :name, 'Bob')).to eql([records.first])
35
+ end
36
+ end
37
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crypt_keeper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 2.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Mazzi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-22 00:00:00.000000000 Z
11
+ date: 2017-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -50,20 +50,6 @@ dependencies:
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
52
  version: '5.2'
53
- - !ruby/object:Gem::Dependency
54
- name: aes
55
- requirement: !ruby/object:Gem::Requirement
56
- requirements:
57
- - - "~>"
58
- - !ruby/object:Gem::Version
59
- version: 0.5.0
60
- type: :runtime
61
- prerelease: false
62
- version_requirements: !ruby/object:Gem::Requirement
63
- requirements:
64
- - - "~>"
65
- - !ruby/object:Gem::Version
66
- version: 0.5.0
67
53
  - !ruby/object:Gem::Dependency
68
54
  name: armor
69
55
  requirement: !ruby/object:Gem::Requirement
@@ -236,13 +222,14 @@ files:
236
222
  - Rakefile
237
223
  - crypt_keeper.gemspec
238
224
  - gemfiles/activerecord_4_2.gemfile
225
+ - gemfiles/activerecord_5_0.gemfile
239
226
  - gemfiles/activerecord_5_1.gemfile
240
227
  - lib/crypt_keeper.rb
241
228
  - lib/crypt_keeper/helper.rb
242
229
  - lib/crypt_keeper/log_subscriber/mysql_aes.rb
243
230
  - lib/crypt_keeper/log_subscriber/postgres_pgp.rb
244
231
  - lib/crypt_keeper/model.rb
245
- - lib/crypt_keeper/provider/aes_new.rb
232
+ - lib/crypt_keeper/provider/active_support.rb
246
233
  - lib/crypt_keeper/provider/base.rb
247
234
  - lib/crypt_keeper/provider/mysql_aes_new.rb
248
235
  - lib/crypt_keeper/provider/postgres_base.rb
@@ -252,7 +239,7 @@ files:
252
239
  - spec/crypt_keeper/log_subscriber/mysql_aes_spec.rb
253
240
  - spec/crypt_keeper/log_subscriber/postgres_pgp_spec.rb
254
241
  - spec/crypt_keeper/model_spec.rb
255
- - spec/crypt_keeper/provider/aes_new_spec.rb
242
+ - spec/crypt_keeper/provider/active_support_spec.rb
256
243
  - spec/crypt_keeper/provider/mysql_aes_new_spec.rb
257
244
  - spec/crypt_keeper/provider/postgres_pgp_public_key_spec.rb
258
245
  - spec/crypt_keeper/provider/postgres_pgp_spec.rb
@@ -267,7 +254,9 @@ homepage: http://jmazzi.github.com/crypt_keeper/
267
254
  licenses:
268
255
  - MIT
269
256
  metadata: {}
270
- post_install_message:
257
+ post_install_message: 'WARNING: CryptKeeper 2.0 contains breaking changes and may
258
+ require you to reencrypt your data! Please view the README at https://github.com/jmazzi/crypt_keeper
259
+ for more information.'
271
260
  rdoc_options: []
272
261
  require_paths:
273
262
  - lib
@@ -278,9 +267,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
278
267
  version: '0'
279
268
  required_rubygems_version: !ruby/object:Gem::Requirement
280
269
  requirements:
281
- - - ">="
270
+ - - ">"
282
271
  - !ruby/object:Gem::Version
283
- version: '0'
272
+ version: 1.3.1
284
273
  requirements: []
285
274
  rubyforge_project:
286
275
  rubygems_version: 2.6.11
@@ -291,7 +280,7 @@ test_files:
291
280
  - spec/crypt_keeper/log_subscriber/mysql_aes_spec.rb
292
281
  - spec/crypt_keeper/log_subscriber/postgres_pgp_spec.rb
293
282
  - spec/crypt_keeper/model_spec.rb
294
- - spec/crypt_keeper/provider/aes_new_spec.rb
283
+ - spec/crypt_keeper/provider/active_support_spec.rb
295
284
  - spec/crypt_keeper/provider/mysql_aes_new_spec.rb
296
285
  - spec/crypt_keeper/provider/postgres_pgp_public_key_spec.rb
297
286
  - spec/crypt_keeper/provider/postgres_pgp_spec.rb
@@ -1,53 +0,0 @@
1
- require 'aes'
2
- require 'armor'
3
-
4
- module CryptKeeper
5
- module Provider
6
- class AesNew < Base
7
- include CryptKeeper::Helper::DigestPassphrase
8
-
9
- # Public: The encryption key
10
- attr_accessor :key
11
-
12
- # Public: Initializes the class
13
- #
14
- # options - A hash of options. :key and :salt are required
15
- def initialize(options = {})
16
- @key = digest_passphrase(options[:key], options[:salt])
17
- end
18
-
19
- # Public: Encrypt a string
20
- #
21
- # Note: nil and empty strings are not encryptable with AES.
22
- # When they are encountered, the orignal value is returned.
23
- # Otherwise, returns the encrypted string
24
- #
25
- # Returns a String
26
- def encrypt(value)
27
- AES.encrypt(value, key)
28
- end
29
-
30
- # Public: Decrypt a string
31
- #
32
- # Note: nil and empty strings are not encryptable with AES (and thus cannot be decrypted).
33
- # When they are encountered, the orignal value is returned.
34
- # Otherwise, returns the decrypted string
35
- #
36
- # Returns a String
37
- def decrypt(value)
38
- AES.decrypt(value, key)
39
- end
40
-
41
- # Public: Search for a record
42
- #
43
- # record - An ActiveRecord collection
44
- # field - The field to search
45
- # criteria - A string to search with
46
- #
47
- # Returns an Enumerable
48
- def search(records, field, criteria)
49
- records.select { |record| record[field] == criteria }
50
- end
51
- end
52
- end
53
- end
@@ -1,41 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe CryptKeeper::Provider::AesNew do
4
- subject { described_class.new(key: 'cake', salt: 'salt') }
5
-
6
- describe "#initialize" do
7
- let(:digested_key) do
8
- ::Armor.digest('cake', 'salt')
9
- end
10
-
11
- specify { expect(subject.key).to eq(digested_key) }
12
- specify { expect { described_class.new }.to raise_error(ArgumentError, "Missing :key") }
13
- end
14
-
15
- describe "#encrypt" do
16
- let(:encrypted) do
17
- subject.encrypt 'string'
18
- end
19
-
20
- specify { expect(encrypted).to_not eq('string') }
21
- specify { expect(encrypted).to_not be_blank }
22
- end
23
-
24
- describe "#decrypt" do
25
- let(:decrypted) do
26
- subject.decrypt "V02ebRU2wLk25AizasROVg==$kE+IpRaUNdBfYqR+WjMqvA=="
27
- end
28
-
29
- specify { expect(decrypted).to eq('string') }
30
- end
31
-
32
- describe "#search" do
33
- let(:records) do
34
- [{ name: 'Bob' }, { name: 'Tim' }]
35
- end
36
-
37
- it "finds the matching record" do
38
- expect(subject.search(records, :name, 'Bob')).to eql([records.first])
39
- end
40
- end
41
- end