blind_index 0.1.0 → 0.1.1
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 +5 -5
- data/.travis.yml +1 -0
- data/CHANGELOG.md +7 -0
- data/README.md +18 -4
- data/blind_index.gemspec +1 -1
- data/lib/blind_index/extensions.rb +15 -5
- data/lib/blind_index/model.rb +5 -2
- data/lib/blind_index/version.rb +1 -1
- data/lib/blind_index.rb +6 -3
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 370f6b1f09b18d3031f83b76785b8604e7ea8efa553a74d205ca874505abf26d
|
4
|
+
data.tar.gz: dd69a591d88afec3cb63433e78cf9d443828b544fe47c965cfbaf65965c4047e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b3e1e1c4a05f421a65039197e8e7ce4db8057d06529c7b01ba69395c207b77ef3bfbf3b8c5bcc208818d96a6dd78c0d1ddfd42e0ceb525e348c390647014b400
|
7
|
+
data.tar.gz: 017240cd3b9c125c5a9d455085825bee6f985dff4db129e0adb54dd032ef5d74281267f2fd39b74f38b4043c04798a87c3e1d79e71d29ce3c093ee95fd3d0060
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# Blind Index
|
2
2
|
|
3
|
-
Securely
|
3
|
+
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
|
+
[](https://travis-ci.org/ankane/blind_index)
|
8
|
+
|
7
9
|
## How It Works
|
8
10
|
|
9
|
-
|
11
|
+
This project uses [this approach](https://www.sitepoint.com/how-to-search-on-securely-encrypted-database-fields/) by Scott Arciszewski. To summarize, we compute a keyed hash of the sensitive data and store it in a column. To query, we apply the keyed hash function (PBKDF2-HMAC-SHA256) to the value we’re searching and then perform a database search. This results in performant queries for equality operations, while keeping the data secure from those without the key.
|
10
12
|
|
11
13
|
## Getting Started
|
12
14
|
|
@@ -70,7 +72,7 @@ You can apply expressions to attributes before indexing and searching. This give
|
|
70
72
|
|
71
73
|
```ruby
|
72
74
|
class User < ApplicationRecord
|
73
|
-
blind_index :email, expression: ->
|
75
|
+
blind_index :email, expression: ->(v) { v.downcase } ...
|
74
76
|
end
|
75
77
|
```
|
76
78
|
|
@@ -88,7 +90,7 @@ And update your model
|
|
88
90
|
```ruby
|
89
91
|
class User < ApplicationRecord
|
90
92
|
blind_index :email, ...
|
91
|
-
blind_index :email_ci, attribute: :email, expression: ->
|
93
|
+
blind_index :email_ci, attribute: :email, expression: ->(v) { v.downcase } ...
|
92
94
|
end
|
93
95
|
```
|
94
96
|
|
@@ -110,6 +112,18 @@ end
|
|
110
112
|
|
111
113
|
The default is `10000`. Changing this value requires you to recompute the blind index.
|
112
114
|
|
115
|
+
## Index Only
|
116
|
+
|
117
|
+
If you don’t need to store the original value (for instance, when just checking duplicates), use a virtual attribute:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
class User < ApplicationRecord
|
121
|
+
attribute :email
|
122
|
+
|
123
|
+
blind_index :email, ...
|
124
|
+
end
|
125
|
+
```
|
126
|
+
|
113
127
|
## History
|
114
128
|
|
115
129
|
View the [changelog](https://github.com/ankane/blind_index/blob/master/CHANGELOG.md)
|
data/blind_index.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Andrew Kane"]
|
10
10
|
spec.email = ["andrew@chartkick.com"]
|
11
11
|
|
12
|
-
spec.summary = "Securely
|
12
|
+
spec.summary = "Securely search encrypted database fields"
|
13
13
|
spec.homepage = "https://github.com/ankane/blind_index"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -23,12 +23,22 @@ module BlindIndex
|
|
23
23
|
end
|
24
24
|
|
25
25
|
module UniquenessValidator
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
if ActiveRecord::VERSION::STRING >= "5.2"
|
27
|
+
def build_relation(klass, attribute, value)
|
28
|
+
if klass.respond_to?(:blind_indexes) && (bi = klass.blind_indexes[attribute])
|
29
|
+
value = BlindIndex.generate_bidx(value, bi)
|
30
|
+
attribute = bi[:bidx_attribute]
|
31
|
+
end
|
32
|
+
super(klass, attribute, value)
|
33
|
+
end
|
34
|
+
else
|
35
|
+
def build_relation(klass, table, attribute, value)
|
36
|
+
if klass.respond_to?(:blind_indexes) && (bi = klass.blind_indexes[attribute])
|
37
|
+
value = BlindIndex.generate_bidx(value, bi)
|
38
|
+
attribute = bi[:bidx_attribute]
|
39
|
+
end
|
40
|
+
super(klass, table, attribute, value)
|
30
41
|
end
|
31
|
-
super(klass, table, attribute, value)
|
32
42
|
end
|
33
43
|
end
|
34
44
|
end
|
data/lib/blind_index/model.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module BlindIndex
|
2
2
|
module Model
|
3
|
-
def blind_index(name, key: nil, iterations: nil, attribute: nil, expression: nil, bidx_attribute: nil)
|
3
|
+
def blind_index(name, key: nil, iterations: nil, attribute: nil, expression: nil, bidx_attribute: nil, callback: true)
|
4
4
|
iterations ||= 10000
|
5
5
|
attribute ||= name
|
6
6
|
bidx_attribute ||= :"encrypted_#{name}_bidx"
|
@@ -26,10 +26,13 @@ module BlindIndex
|
|
26
26
|
bidx_attribute: bidx_attribute
|
27
27
|
}
|
28
28
|
|
29
|
-
before_validation method_name, if: -> { changes.key?(attribute.to_s) }
|
30
29
|
define_method method_name do
|
31
30
|
self.send("#{bidx_attribute}=", BlindIndex.generate_bidx(send(attribute), self.class.blind_indexes[name]))
|
32
31
|
end
|
32
|
+
|
33
|
+
if callback
|
34
|
+
before_validation method_name, if: -> { changes.key?(attribute.to_s) }
|
35
|
+
end
|
33
36
|
end
|
34
37
|
end
|
35
38
|
end
|
data/lib/blind_index/version.rb
CHANGED
data/lib/blind_index.rb
CHANGED
@@ -2,14 +2,15 @@
|
|
2
2
|
require "active_support"
|
3
3
|
|
4
4
|
# modules
|
5
|
-
require "blind_index/extensions"
|
6
5
|
require "blind_index/model"
|
7
6
|
require "blind_index/version"
|
8
7
|
|
9
8
|
module BlindIndex
|
10
|
-
class Error; end
|
9
|
+
class Error < StandardError; end
|
11
10
|
|
12
11
|
def self.generate_bidx(value, key:, iterations:, expression: nil, **options)
|
12
|
+
key = key.call if key.respond_to?(:call)
|
13
|
+
|
13
14
|
raise BlindIndex::Error, "Missing key for blind index" unless key
|
14
15
|
|
15
16
|
# apply expression
|
@@ -25,9 +26,11 @@ module BlindIndex
|
|
25
26
|
end
|
26
27
|
|
27
28
|
ActiveSupport.on_load(:active_record) do
|
29
|
+
require "blind_index/extensions"
|
28
30
|
extend BlindIndex::Model
|
29
31
|
ActiveRecord::TableMetadata.prepend(BlindIndex::Extensions::TableMetadata)
|
30
|
-
|
32
|
+
|
33
|
+
unless ActiveRecord::VERSION::STRING.start_with?("5.1.")
|
31
34
|
ActiveRecord::Validations::UniquenessValidator.prepend(BlindIndex::Extensions::UniquenessValidator)
|
32
35
|
end
|
33
36
|
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.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -149,8 +149,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
149
|
version: '0'
|
150
150
|
requirements: []
|
151
151
|
rubyforge_project:
|
152
|
-
rubygems_version: 2.6
|
152
|
+
rubygems_version: 2.7.6
|
153
153
|
signing_key:
|
154
154
|
specification_version: 4
|
155
|
-
summary: Securely
|
155
|
+
summary: Securely search encrypted database fields
|
156
156
|
test_files: []
|