pod4 0.10.3 → 0.10.4

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: c65450007521cb6a9e312bdc47350624c85f381f
4
- data.tar.gz: 37a401097db2e57f2ea96c337e4b3e151a154606
3
+ metadata.gz: 630728075021ff016e6ead3d63c58806821bc3ce
4
+ data.tar.gz: 8545dc27e2f1f73a7fd4bc0589d4f751a44d3811
5
5
  SHA512:
6
- metadata.gz: c7c157f8b35a9961a48e9457e7aa328dd1a4c361876aa236cdfbe009448a21e005c659fa7a089c79f4e61d169580d622e5539d3b04cf4d78f293422b0e20dc8e
7
- data.tar.gz: 5be81a188a0e925fdbb45cb4f1bb74240eed34b16c6e103ce75905aefe3bc378354c744cf8437fca0389b1c68b82ef2f6fdb21b0b14a26672babcb133838c6e4
6
+ metadata.gz: b93e6dc86f29c31acca757cb64392a23b406829f033e6db3a4c0158e951ce258a5abe874d6f6f3f393b03afc84b0a8d3db461d0fdf6e189cee545c201adc8d41
7
+ data.tar.gz: f07ac222e7260b0fd94669640fc519a14604779982d659333da5de52577e590cf811665645fd2192ec277b80d56765ac35e57e1689c5dec21c27c712d58b6f02
data/.hgtags CHANGED
@@ -29,3 +29,4 @@ f1b3a814e7a8c7d818b57f6d35ce7ed749573d76 0.9.1
29
29
  77ad625b2ab048bd660194cf093015b1f2698069 0.10
30
30
  7ac52e99228fe39ca59c87fad8fe2c1236fce4fa 0.10.1
31
31
  7a39c71dceaf05b9204e1f2870f904940fdac4d3 0.10.3
32
+ e98232cdc6cbe61e2bf0513fcf578001a2931018 0.10.4
@@ -75,6 +75,10 @@ module Pod4
75
75
  #
76
76
  # * `encryption_iv` returns the value of the IV column of the record, whatever it is.
77
77
  #
78
+ # * `encrypt` and `decrypt` allow you to transform arbitrary text in a manner compatible with the
79
+ # model -- for example, if you removed a column from `encrypted_columns`, you could do a
80
+ # one-time decrypt of your data.
81
+ #
78
82
  # Notes
79
83
  # -----
80
84
  #
@@ -135,12 +139,11 @@ module Pod4
135
139
  hash = super.to_h
136
140
  cipher = get_cipher(:encrypt)
137
141
 
138
- # If the IV is not set we need to set it both in the model object AND the hash, since we've
139
- # already obtained the hash from the model object.
140
- if use_iv? && encryption_iv.nil?
141
- iv = cipher.random_iv
142
- set_encryption_iv(iv)
143
- hash[self.class.encryption_iv_column] = Base64.strict_encode64(iv)
142
+ # Each time we write, we set a new IV. We must also set it on the hash to go to the
143
+ # interface, where it must be base64 encoded, just like the encrypted columns.
144
+ if use_iv?
145
+ set_encryption_iv( cipher.random_iv )
146
+ hash[self.class.encryption_iv_column] = Base64.strict_encode64(encryption_iv)
144
147
  end
145
148
 
146
149
  self.class.encryption_columns.each do |col|
@@ -157,10 +160,9 @@ module Pod4
157
160
  hash = ot.to_h
158
161
  cipher = get_cipher(:decrypt)
159
162
 
160
- # The IV is not in columns, we need to de-base-64 it and set it on the model ourselves
161
- if use_iv?
162
- iv = Base64.strict_decode64 hash[self.class.encryption_iv_column]
163
- set_encryption_iv(iv)
163
+ # The IV column is not in columns, so we need to de-base-64 it and set it on the model here
164
+ if use_iv? && (iv64 = hash[self.class.encryption_iv_column])
165
+ set_encryption_iv Base64.strict_decode64(iv64)
164
166
  end
165
167
 
166
168
  self.class.encryption_columns.each do |col|
@@ -178,6 +180,24 @@ module Pod4
178
180
  instance_variable_get( "@#{self.class.encryption_iv_column}".to_sym )
179
181
  end
180
182
 
183
+ ##
184
+ # Public facing manual encryption, compatible with the current model
185
+ #
186
+ def encrypt(string)
187
+ cipher = get_cipher(:encrypt)
188
+ iv = use_iv? ? encryption_iv : nil
189
+ crypt(cipher, :encrypt, iv, string)
190
+ end
191
+
192
+ ##
193
+ # Public facing manual decryption, compatible with the current model
194
+ #
195
+ def decrypt(string)
196
+ cipher = get_cipher(:decrypt)
197
+ iv = use_iv? ? encryption_iv : nil
198
+ crypt(cipher, :decrypt, iv, string)
199
+ end
200
+
181
201
  private
182
202
 
183
203
  ##
@@ -219,14 +239,16 @@ module Pod4
219
239
  cipher.key = self.class.encryption_key
220
240
  cipher.iv = iv if use_iv?
221
241
 
222
- string = Base64.strict_decode64(string) if direction == :decrypt
223
-
224
- answer = ""
225
- answer << cipher.update(string.to_s) unless direction == :encrypt && string.empty?
226
- answer << cipher.final
227
-
228
- answer = Base64.strict_encode64(answer) if direction == :encrypt
229
- answer
242
+ case direction
243
+ when :encrypt
244
+ answer = string.to_s.empty? ? "" : cipher.update(string.to_s)
245
+ answer << cipher.final
246
+ Base64.strict_encode64(answer)
247
+
248
+ when :decrypt
249
+ answer = Base64.strict_decode64(string.to_s)
250
+ cipher.update(answer) + cipher.final
251
+ end
230
252
 
231
253
  rescue OpenSSL::Cipher::CipherError
232
254
  raise Pod4::Pod4Error, $!
data/lib/pod4/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pod4
2
- VERSION = '0.10.3'
2
+ VERSION = '0.10.4'
3
3
  end
@@ -229,7 +229,7 @@ describe "(Model with Encryption)" do
229
229
  expect( d.heading ).to eq "fred"
230
230
  expect( d.text ).to eq "sore toe"
231
231
  end
232
-
232
+
233
233
  end
234
234
 
235
235
  context "when we have an IV column" do
@@ -249,6 +249,24 @@ describe "(Model with Encryption)" do
249
249
  expect( m.prescription ).to eq "suck thumb"
250
250
  end
251
251
 
252
+ it "handles the case of a record with no IV (not encrypted)" do
253
+ ot = Octothorpe.new( id: 80,
254
+ nhs_no: "abc",
255
+ name: "sally",
256
+ ailment: "short-sighted",
257
+ prescription: "glasses",
258
+ nonce: nil )
259
+
260
+ m80 = medical_model_class.new(80)
261
+ allow( m80.interface ).to receive(:read).with(80).and_return(ot)
262
+
263
+ m80.read
264
+ expect( m80.nhs_no ).to eq "abc"
265
+ expect( m80.name ).to eq "sally"
266
+ expect( m80.ailment ).to eq "short-sighted"
267
+ expect( m80.prescription ).to eq "glasses"
268
+ end
269
+
252
270
  end
253
271
 
254
272
  end # of (reading a record)
@@ -294,6 +312,21 @@ describe "(Model with Encryption)" do
294
312
  end # of Model#encryption_iv
295
313
 
296
314
 
315
+ describe "Model#encrypt & Model#decrypt" do
316
+
317
+ it "encrypts and decrypts when the model has no IV" do
318
+ d = diary_model_class.new
319
+ expect( d.decrypt(d.encrypt "foobar123") ).to eq "foobar123"
320
+ end
321
+
322
+ it "encrypts and decrypts when the model has IV" do
323
+ m = medical_model_class.new
324
+ expect( m.decrypt(m.encrypt "plonkplink987") ).to eq "plonkplink987"
325
+ end
326
+
327
+ end # of Model#encrypt & Model#decrypt
328
+
329
+
297
330
  describe "Model#map_to_interface" do
298
331
 
299
332
  it "raises Pod4Error if there is an encryption problem, eg, key too short" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pod4
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.3
4
+ version: 0.10.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Jones
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-07 00:00:00.000000000 Z
11
+ date: 2018-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: devnull