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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 21c05c3393cf49eaf7ebd8b45b872724bbb2344c
4
- data.tar.gz: 11cf069f14be218a178bebb0acb646f0d293b4d1
3
+ metadata.gz: 1475a0799bf0c7185a9c8e00d68258518bfe98af
4
+ data.tar.gz: 3f15bda52a73b7ef212dcc9b47196ca86adf0979
5
5
  SHA512:
6
- metadata.gz: cfb79ccabcef173c20cdaa045ae685215890df0559276f0915387abaa203088fd834d87d4c0973e8123466de8264fa0482d547b8f969722e90442da2b8e90645
7
- data.tar.gz: 840f2ce58bec117ec31afebf3bc91f6001eb4647c400d8f2a724caea4349c7da8182dcd9ecb1ee39b66b33c85564f3cd6c7503111835b7ebec3ed4b6e1edf3fe
6
+ metadata.gz: c632a1359f36fe0e9595397c7cd4e00210ecd9bb860e6ece61b7ceb6b2a39759d48add5c0ce7a1b67d00565305bc2f28ecb49ff1d5e62092e4f6b2b716e3a38c
7
+ data.tar.gz: ac247318fd969ac4fddeb6d1993590847c2d6a83aec9e980a9d1326d4a84e6bb4aa5ad5e923f62353f89a749d68c670db2c7b14bcd4a4341c8b8d7f25321b227
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # hash_redactor #
2
2
 
3
+ ##0.3.0 ##
4
+ * Added: Whitelist mode (@chrisjensen)
5
+ * Fixed: redact + decrypt loop specs should check result is not empty (@chrisjensen)
6
+
3
7
  ##0.2.1 ##
4
8
  * Fixed: Add support for string keys (@chrisjensen)
5
9
 
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
- redact_hash.each do |hash_key,how|
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
- digest_key = hash_key.to_s + '_digest'
60
- digest_key = digest_key.to_sym if hash_key.is_a? Symbol
79
+ dig_key = digest_key hash_key
61
80
 
62
- hash[digest_key] = Digest::SHA256.base64digest(
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
@@ -1,3 +1,3 @@
1
1
  module HashRedactor
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
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.2.1
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-10 00:00:00.000000000 Z
11
+ date: 2016-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: attr_encrypted