hash_redactor 0.2.1 → 0.3.0
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 +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
|