blind_index 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/ankane/blind_index.svg?branch=master)](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: []
|