pod4 0.10.3 → 0.10.4

Sign up to get free protection for your applications and to get access to all the features.
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