hash_redactor 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +48 -1
- data/lib/hash_redactor/hash_redactor.rb +47 -6
- data/lib/hash_redactor/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1475a0799bf0c7185a9c8e00d68258518bfe98af
|
4
|
+
data.tar.gz: 3f15bda52a73b7ef212dcc9b47196ca86adf0979
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c632a1359f36fe0e9595397c7cd4e00210ecd9bb860e6ece61b7ceb6b2a39759d48add5c0ce7a1b67d00565305bc2f28ecb49ff1d5e62092e4f6b2b716e3a38c
|
7
|
+
data.tar.gz: ac247318fd969ac4fddeb6d1993590847c2d6a83aec9e980a9d1326d4a84e6bb4aa5ad5e923f62353f89a749d68c670db2c7b14bcd4a4341c8b8d7f25321b227
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -34,6 +34,7 @@ Initialize the HashRedactor with a set of fields that you want to redact in hash
|
|
34
34
|
|
35
35
|
You can choose 3 ways to redact each field:
|
36
36
|
|
37
|
+
+ `:keep` - The field is untouched (for use in `:whitelist` mode)
|
37
38
|
+ `:remove` - The field is simply deleted
|
38
39
|
+ `:digest` - The field is passed through a one way hash function (SHA256)
|
39
40
|
+ `:encrypt` - The field is encrypted
|
@@ -121,7 +122,8 @@ Default options are:
|
|
121
122
|
encryption_key: nil,
|
122
123
|
encode: true,
|
123
124
|
encode_iv: true,
|
124
|
-
default_encoding: 'm'
|
125
|
+
default_encoding: 'm',
|
126
|
+
filter_mode: :blacklist
|
125
127
|
```
|
126
128
|
|
127
129
|
### :digest_salt
|
@@ -138,6 +140,51 @@ Determines how (if at all) to encode the encrypted data and it's iv
|
|
138
140
|
|
139
141
|
The default encoding is m (base64). You can change this by setting encode: `'some encoding'`. See [Arrary#pack](http://ruby-doc.org/core-2.3.0/Array.html#method-i-pack) for more encoding options.
|
140
142
|
|
143
|
+
### filter_mode
|
144
|
+
|
145
|
+
Filter mode determines how keys that are not included in the redact option are handled.
|
146
|
+
It can be either `:whitelist` or `:blacklist`
|
147
|
+
|
148
|
+
In `:blacklist` mode the default, it will leave unspecified keys untouched.
|
149
|
+
In `:whitelist` mode any keys not specified will be removes.
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
redactor = HashRedactor::HashRedactor.new({
|
153
|
+
redact: { :id => :keep, :ssn => :remove, :history => :encrypt, :email => :digest" },
|
154
|
+
encryption_key: 'a really secure key no one will ever guess it',
|
155
|
+
digest_salt: 'a secret salt'
|
156
|
+
})
|
157
|
+
|
158
|
+
data = {
|
159
|
+
id: 42,
|
160
|
+
ssn: 'my ssn number',
|
161
|
+
history: 'Intriguing"
|
162
|
+
email: 'personal@email.com',
|
163
|
+
age: "that's personal"
|
164
|
+
}
|
165
|
+
|
166
|
+
result = reactor.redact data
|
167
|
+
result[:id] # 42
|
168
|
+
result[:ssn] # nil
|
169
|
+
result[:encrypted_history] # encrypted value
|
170
|
+
result[:email_digest] # digest of email
|
171
|
+
|
172
|
+
result[:age] # "that's personal"
|
173
|
+
|
174
|
+
result = reactor.redact data, :filter_mode => :whitelist
|
175
|
+
|
176
|
+
result[:id] # 42 (because of :id => :keep)
|
177
|
+
result[:ssn] # nil
|
178
|
+
result[:encrypted_history] # encrypted value
|
179
|
+
result[:email_digest] # digest of email
|
180
|
+
|
181
|
+
result[:age] # nil (because it wasn't explicitly whitelisted)
|
182
|
+
|
183
|
+
```
|
184
|
+
|
185
|
+
*Note:* To prevent accidental deletion of digest information during repeated loading and unloading data, the digest of all values is implicitly assumed to be :keep.
|
186
|
+
eg If your redact hash includes `:email => :digest`, it is assumed to also contain `:email_digest => :keep`
|
187
|
+
|
141
188
|
## Development
|
142
189
|
|
143
190
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -7,6 +7,8 @@ module HashRedactor
|
|
7
7
|
|
8
8
|
@options[:encode] = @options[:default_encoding] if @options[:encode] == true
|
9
9
|
@options[:encode_iv] = @options[:default_encoding] if @options[:encode_iv] == true
|
10
|
+
|
11
|
+
raise "unknown filter mode #{@options[:filter_mode]}" unless [:blacklist,:whitelist].include? @options[:filter_mode]
|
10
12
|
end
|
11
13
|
|
12
14
|
def default_options
|
@@ -15,9 +17,14 @@ module HashRedactor
|
|
15
17
|
encryption_key: nil,
|
16
18
|
encode: true,
|
17
19
|
encode_iv: true,
|
18
|
-
default_encoding: 'm'
|
20
|
+
default_encoding: 'm',
|
21
|
+
filter_mode: :blacklist
|
19
22
|
}
|
20
23
|
end
|
24
|
+
|
25
|
+
def options
|
26
|
+
@options
|
27
|
+
end
|
21
28
|
|
22
29
|
# Removes, digests or encrypts fields in a hash
|
23
30
|
# NOTE: This should NOT be used to protect password fields or similar
|
@@ -35,9 +42,22 @@ module HashRedactor
|
|
35
42
|
|
36
43
|
result = data.clone
|
37
44
|
|
38
|
-
|
45
|
+
# If it's blacklist mode, just go over our redact keys
|
46
|
+
# Otherwise, we have to go through and remove all keys that aren't :keep
|
47
|
+
if (options[:filter_mode] == :whitelist)
|
48
|
+
keys = data.keys
|
49
|
+
redact_hash = whitelist_redact_hash redact_hash
|
50
|
+
else
|
51
|
+
keys = redact_hash.keys
|
52
|
+
end
|
53
|
+
|
54
|
+
keys.each do |hash_key,how|
|
55
|
+
how = redact_hash[hash_key] || :remove
|
56
|
+
|
39
57
|
if data.has_key? hash_key
|
40
58
|
case how
|
59
|
+
when :keep
|
60
|
+
nil
|
41
61
|
when :remove
|
42
62
|
nil
|
43
63
|
when :digest
|
@@ -48,7 +68,7 @@ module HashRedactor
|
|
48
68
|
raise "redact called with unknown operation on #{hash_key}: #{how}"
|
49
69
|
end
|
50
70
|
|
51
|
-
result.delete hash_key
|
71
|
+
result.delete hash_key unless how == :keep
|
52
72
|
end
|
53
73
|
end
|
54
74
|
|
@@ -56,10 +76,9 @@ module HashRedactor
|
|
56
76
|
end
|
57
77
|
|
58
78
|
def digest(hash, hash_key, options)
|
59
|
-
|
60
|
-
digest_key = digest_key.to_sym if hash_key.is_a? Symbol
|
79
|
+
dig_key = digest_key hash_key
|
61
80
|
|
62
|
-
hash[
|
81
|
+
hash[dig_key] = Digest::SHA256.base64digest(
|
63
82
|
hash[hash_key].to_s + options[:digest_salt])
|
64
83
|
end
|
65
84
|
|
@@ -134,6 +153,28 @@ module HashRedactor
|
|
134
153
|
result.delete iv_key
|
135
154
|
end
|
136
155
|
end
|
156
|
+
|
157
|
+
def digest_key hash_key
|
158
|
+
dig_key = hash_key.to_s + '_digest'
|
159
|
+
dig_key = dig_key.to_sym if hash_key.is_a? Symbol
|
160
|
+
dig_key
|
161
|
+
end
|
162
|
+
|
163
|
+
# Calculate all keys that should be kept in whitelist mode
|
164
|
+
# In multiple iterations of redact -> decrypt - digest keys will remain
|
165
|
+
# and then get deleted in the second iteration, so we have to
|
166
|
+
# add the digest keys so they're not wiped out on later iteration
|
167
|
+
def whitelist_redact_hash redact_hash
|
168
|
+
digest_hash = {}
|
169
|
+
|
170
|
+
redact_hash.each do |key,how|
|
171
|
+
if (how == :digest)
|
172
|
+
digest_hash[digest_key(key)] = :keep
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
digest_hash.merge redact_hash
|
177
|
+
end
|
137
178
|
end
|
138
179
|
|
139
180
|
class EncryptorInterface
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hash_redactor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Jensen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-07-
|
11
|
+
date: 2016-07-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: attr_encrypted
|