blind_index 0.3.2 → 0.3.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe8410b6e972d6fe7aa37648396462b1e2a70358813e97db153d62ed5ac3fbad
4
- data.tar.gz: 37d9baa7fb293ee2aa6e0a9fb5d253f8d0c7a83807dade72a8ac532825dc0220
3
+ metadata.gz: 26d5a803099fa8b408065a43056697f24eaf10a89c6a778979e5bdd8d54bbb5e
4
+ data.tar.gz: '0288069afcdd54f3f3917ef25177550bd3c912333aca346d1ae77d0d237eb5ce'
5
5
  SHA512:
6
- metadata.gz: c647598d872e02b829377d5436442f0d929575722ee3330396c773d4dea556aabf74083e4868923fb597478df5648487fbfa26361eb6a341b1709dea3bb2e137
7
- data.tar.gz: 1a9c501115e25cecf73e59ccb7ee5b23c96ccb01c81e4a62e48c1858546cf67a9c83f4f482cbf212ca2f38de559bbb668c39bf90a131ede9732eb4e390f45d3b
6
+ metadata.gz: 1f062a2b9d1aa2d251dd38b6c815423afa146a34df0825d655bd9ac0ea666af9d0382d958995c7899e16a729b15e7e3d696d661485a246220e93bade67104641
7
+ data.tar.gz: 1478bb3716c6ad099e42ed95b286d7aa5a13c6be7f75d4ec6e7d5c82898c95d1fc7db2537d53c6daa5754ad398579bca5e924a60551423402e064f24b52ee2ff
@@ -1,3 +1,7 @@
1
+ ## 0.3.3
2
+
3
+ - Added support for string keys in finders
4
+
1
5
  ## 0.3.2
2
6
 
3
7
  - Added support for dynamic finders
data/README.md CHANGED
@@ -4,7 +4,7 @@ Securely search encrypted database fields
4
4
 
5
5
  Designed for use with [attr_encrypted](https://github.com/attr-encrypted/attr_encrypted)
6
6
 
7
- Here’s a [full example](https://shorts.dokkuapp.com/securing-user-emails-in-rails/) of how to use it with Devise
7
+ Here’s a [full example](https://ankane.org/securing-user-emails-in-rails) of how to use it with Devise
8
8
 
9
9
  [![Build Status](https://travis-ci.org/ankane/blind_index.svg?branch=master)](https://travis-ci.org/ankane/blind_index)
10
10
 
@@ -42,7 +42,7 @@ class User < ApplicationRecord
42
42
  end
43
43
  ```
44
44
 
45
- We use environment variables to store the keys as hex-encoded strings ([dotenv](https://github.com/bkeepers/dotenv) is great for this). *Do not commit them to source control.* Generate one key for encryption and one key for hashing. You can generate keys in the Rails console with:
45
+ We use environment variables to store the keys as hex-encoded strings ([dotenv](https://github.com/bkeepers/dotenv) is great for this). [Here’s an explanation](https://ankane.org/encryption-keys) of why `pack` is used. *Do not commit them to source control.* Generate one key for encryption and one key for hashing. You can generate keys in the Rails console with:
46
46
 
47
47
  ```ruby
48
48
  SecureRandom.hex(32)
@@ -118,12 +118,36 @@ class User < ApplicationRecord
118
118
  end
119
119
  ```
120
120
 
121
+ *Requires ActiveRecord 5.1+*
122
+
123
+ ## Multiple Columns
124
+
125
+ You can also use virtual attributes to index data from multiple columns:
126
+
127
+ ```ruby
128
+ class User < ApplicationRecord
129
+ attribute :initials
130
+
131
+ # must come before blind_index method
132
+ before_validation :set_initials, if: -> { changes.key?(:first_name) || changes.key?(:last_name) }
133
+ blind_index :initials, ...
134
+
135
+ def set_initials
136
+ self.initials = "#{first_name[0]}#{last_name[0]}"
137
+ end
138
+ end
139
+ ```
140
+
141
+ *Requires ActiveRecord 5.1+*
142
+
121
143
  ## Fixtures
122
144
 
123
- You can use blind indexes in fixtures with:
145
+ You can use encrypted attributes and blind indexes in fixtures with:
124
146
 
125
147
  ```yml
126
148
  test_user:
149
+ encrypted_email: <%= User.encrypt_email("test@example.org", iv: Base64.decode64("0000000000000000")) %>
150
+ encrypted_email_iv: "0000000000000000"
127
151
  encrypted_email_bidx: <%= User.compute_email_bidx("test@example.org").inspect %>
128
152
  ```
129
153
 
@@ -179,6 +203,46 @@ class User < ApplicationRecord
179
203
  end
180
204
  ```
181
205
 
206
+ ## Key Rotation
207
+
208
+ To rotate keys without downtime, add a new column:
209
+
210
+ ```ruby
211
+ add_column :users, :encrypted_email_v2_bidx, :string
212
+ add_index :users, :encrypted_email_v2_bidx
213
+ ```
214
+
215
+ And add to your model
216
+
217
+ ```ruby
218
+ class User < ApplicationRecord
219
+ blind_index :email, key: [ENV["EMAIL_BLIND_INDEX_KEY"]].pack("H*")
220
+ blind_index :email_v2, attribute: :email, key: [ENV["EMAIL_V2_BLIND_INDEX_KEY"]].pack("H*")
221
+ end
222
+ ```
223
+
224
+ Backfill the data
225
+
226
+ ```ruby
227
+ User.find_each do |user|
228
+ user.compute_email_v2_bidx
229
+ user.save!
230
+ end
231
+ ```
232
+
233
+ Then update your model
234
+
235
+ ```ruby
236
+ class User < ApplicationRecord
237
+ blind_index :email, bidx_attribute: :encrypted_email_v2_bidx, key: [ENV["EMAIL_V2_BLIND_INDEX_KEY"]].pack("H*")
238
+
239
+ # remove this line after dropping column
240
+ self.ignored_columns = ["encrypted_email_bidx"]
241
+ end
242
+ ```
243
+
244
+ Finally, drop the old column.
245
+
182
246
  ## Reference
183
247
 
184
248
  By default, blind indexes are encoded in Base64. Set a different encoding with:
@@ -6,7 +6,7 @@ module BlindIndex
6
6
  new_hash = super
7
7
  if has_blind_indexes?
8
8
  hash.each do |key, _|
9
- if (bi = klass.blind_indexes[key]) && !new_hash[key].is_a?(ActiveRecord::StatementCache::Substitute)
9
+ if key.respond_to?(:to_sym) && (bi = klass.blind_indexes[key.to_sym]) && !new_hash[key].is_a?(ActiveRecord::StatementCache::Substitute)
10
10
  new_hash[bi[:bidx_attribute]] = BlindIndex.generate_bidx(new_hash.delete(key), bi)
11
11
  end
12
12
  end
@@ -29,7 +29,7 @@ module BlindIndex
29
29
  new_hash = super
30
30
  if has_blind_indexes?(klass)
31
31
  hash.each do |key, _|
32
- if (bi = klass.blind_indexes[key]) && !new_hash[key].is_a?(ActiveRecord::StatementCache::Substitute)
32
+ if key.respond_to?(:to_sym) && (bi = klass.blind_indexes[key.to_sym]) && !new_hash[key].is_a?(ActiveRecord::StatementCache::Substitute)
33
33
  new_hash[bi[:bidx_attribute]] = BlindIndex.generate_bidx(new_hash.delete(key), bi)
34
34
  end
35
35
  end
@@ -49,7 +49,12 @@ module BlindIndex
49
49
  end
50
50
 
51
51
  if callback
52
- before_validation method_name, if: -> { changes.key?(attribute.to_s) }
52
+ if ActiveRecord::VERSION::STRING >= "5.1"
53
+ before_validation method_name, if: :"will_save_change_to_#{attribute}?"
54
+ else
55
+ before_validation method_name, if: -> { changes.key?(attribute.to_s) }
56
+ end
57
+
53
58
  end
54
59
 
55
60
  # use include so user can override
@@ -1,3 +1,3 @@
1
1
  module BlindIndex
2
- VERSION = "0.3.2"
2
+ VERSION = "0.3.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blind_index
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-18 00:00:00.000000000 Z
11
+ date: 2018-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -151,22 +151,14 @@ dependencies:
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  description:
154
- email:
155
- - andrew@chartkick.com
154
+ email: andrew@chartkick.com
156
155
  executables: []
157
156
  extensions: []
158
157
  extra_rdoc_files: []
159
158
  files:
160
- - ".gitignore"
161
- - ".travis.yml"
162
159
  - CHANGELOG.md
163
- - Gemfile
164
160
  - LICENSE.txt
165
161
  - README.md
166
- - Rakefile
167
- - bin/console
168
- - bin/setup
169
- - blind_index.gemspec
170
162
  - lib/blind_index.rb
171
163
  - lib/blind_index/extensions.rb
172
164
  - lib/blind_index/model.rb
@@ -183,7 +175,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
183
175
  requirements:
184
176
  - - ">="
185
177
  - !ruby/object:Gem::Version
186
- version: '0'
178
+ version: '2.2'
187
179
  required_rubygems_version: !ruby/object:Gem::Requirement
188
180
  requirements:
189
181
  - - ">="
@@ -191,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
191
183
  version: '0'
192
184
  requirements: []
193
185
  rubyforge_project:
194
- rubygems_version: 2.7.6
186
+ rubygems_version: 2.7.7
195
187
  signing_key:
196
188
  specification_version: 4
197
189
  summary: Securely search encrypted database fields
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
- *.lock
@@ -1,14 +0,0 @@
1
- language: ruby
2
- rvm: 2.4.2
3
- gemfile:
4
- - Gemfile
5
- - test/gemfiles/activerecord51.gemfile
6
- - test/gemfiles/activerecord50.gemfile
7
- - test/gemfiles/activerecord42.gemfile
8
- sudo: false
9
- before_install: gem install bundler
10
- script: bundle exec rake test
11
- notifications:
12
- email:
13
- on_success: never
14
- on_failure: change
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- # Specify your gem's dependencies in blind_index.gemspec
4
- gemspec
data/Rakefile DELETED
@@ -1,56 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
8
- t.warning = false
9
- end
10
-
11
- task default: :test
12
-
13
- namespace :benchmark do
14
- task :algorithms do
15
- require "securerandom"
16
- require "benchmark/ips"
17
- require "blind_index"
18
- require "scrypt"
19
- require "argon2"
20
-
21
- key = SecureRandom.random_bytes(32)
22
- value = "secret"
23
-
24
- Benchmark.ips do |x|
25
- x.report("pbkdf2_hmac") { BlindIndex.generate_bidx(value, key: key, algorithm: :pbkdf2_hmac) }
26
- x.report("scrypt") { BlindIndex.generate_bidx(value, key: key, algorithm: :scrypt) }
27
- x.report("argon2") { BlindIndex.generate_bidx(value, key: key, algorithm: :argon2) }
28
- end
29
- end
30
-
31
- task :queries do
32
- require "benchmark/ips"
33
- require "active_record"
34
- require "blind_index"
35
-
36
- ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
37
-
38
- ActiveRecord::Migration.create_table :users do
39
- end
40
-
41
- ActiveRecord::Migration.create_table :cities do
42
- end
43
-
44
- class User < ActiveRecord::Base
45
- blind_index :email
46
- end
47
-
48
- class City < ActiveRecord::Base
49
- end
50
-
51
- Benchmark.ips do |x|
52
- x.report("no index") { City.where(id: 1).first }
53
- x.report("index") { User.where(id: 1).first }
54
- end
55
- end
56
- end
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "blind_index"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -1,34 +0,0 @@
1
-
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "blind_index/version"
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "blind_index"
8
- spec.version = BlindIndex::VERSION
9
- spec.authors = ["Andrew Kane"]
10
- spec.email = ["andrew@chartkick.com"]
11
-
12
- spec.summary = "Securely search encrypted database fields"
13
- spec.homepage = "https://github.com/ankane/blind_index"
14
- spec.license = "MIT"
15
-
16
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
- f.match(%r{^(test|spec|features)/})
18
- end
19
- spec.bindir = "exe"
20
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
- spec.require_paths = ["lib"]
22
-
23
- spec.add_dependency "activesupport", ">= 4.2"
24
-
25
- spec.add_development_dependency "bundler"
26
- spec.add_development_dependency "rake"
27
- spec.add_development_dependency "minitest"
28
- spec.add_development_dependency "attr_encrypted"
29
- spec.add_development_dependency "activerecord"
30
- spec.add_development_dependency "sqlite3"
31
- spec.add_development_dependency "scrypt"
32
- spec.add_development_dependency "argon2"
33
- spec.add_development_dependency "benchmark-ips"
34
- end