lockbox 0.5.0 → 0.6.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
  SHA256:
3
- metadata.gz: '00428f366a284e5e69806c18ef64a7bb66cdc0b2c1cb3e19528aa6bca99becea'
4
- data.tar.gz: b5235c68771e0cb39653780dd4e08bdb27218f914b3889cecf959bc02efec3a8
3
+ metadata.gz: 77945cdf065bda9282a4a9cbffd77ebe518bcbe11c3e3ccaa91768bd1579f94c
4
+ data.tar.gz: ab052f812a91e1620dcc52ac578006b55e84d5aae1770ecb5c6c89c5119f9073
5
5
  SHA512:
6
- metadata.gz: cd44c7b55ea270aa02fa5a4eda5aa38bde97eca39ce54093b6fc4907abe90e946827b4c12a8f5f43f21b6503ea9d1c713f505a86c9a6ea4075b1407b5630aeca
7
- data.tar.gz: 0eba333d509de09a92cd1af74427cce30eca35d7eab41abddada5718227c5a1f3f013b3ad031f8015ca5e13c4b47f5aebe75c09d83f6bd91926ad7d55db6a1e4
6
+ metadata.gz: 8223d89af7efa1e4192c48512a45177d877df2c1878da425b05bf4e2b066c1f3a413b57f8f0fbdc73a04f000db191bfde2ef8bb0319c4bce7eee6a1985a3771f
7
+ data.tar.gz: 7bcb4b647f4abdc8141c571441ce1c8e47b5864aee3e043cd7f620ca7f9abc208ddb1134ac6f35700c73a30f934c56169ff5bca235ba32faba4a0d2325bc926a
@@ -1,3 +1,9 @@
1
+ ## 0.6.0 (2020-12-03)
2
+
3
+ - Added `encrypted` flag to Active Storage metadata
4
+ - Added encrypted columns to `filter_attributes`
5
+ - Improved `inspect` method
6
+
1
7
  ## 0.5.0 (2020-11-22)
2
8
 
3
9
  - Improved error messages for hybrid cryptography
data/README.md CHANGED
@@ -197,6 +197,34 @@ class User < ApplicationRecord
197
197
  end
198
198
  ```
199
199
 
200
+ #### Model Changes
201
+
202
+ If tracking changes to model attributes, be sure to remove or redact encrypted attributes.
203
+
204
+ PaperTrail
205
+
206
+ ```ruby
207
+ class User < ApplicationRecord
208
+ # for an encrypted history (still tracks ciphertext changes)
209
+ has_paper_trail skip: [:email]
210
+
211
+ # for no history (add blind indexes as well)
212
+ has_paper_trail skip: [:email, :email_ciphertext]
213
+ end
214
+ ```
215
+
216
+ Audited
217
+
218
+ ```ruby
219
+ class User < ApplicationRecord
220
+ # for an encrypted history (still tracks ciphertext changes)
221
+ audited except: [:email]
222
+
223
+ # for no history (add blind indexes as well)
224
+ audited except: [:email, :email_ciphertext]
225
+ end
226
+ ```
227
+
200
228
  #### Decryption
201
229
 
202
230
  To decrypt data outside the model, use:
@@ -731,14 +759,14 @@ For Ubuntu 20.04 and 18.04, use:
731
759
 
732
760
  ```yml
733
761
  - name: Install Libsodium
734
- run: sudo apt-get install libsodium23
762
+ run: sudo apt-get update && sudo apt-get install libsodium23
735
763
  ```
736
764
 
737
765
  For Ubuntu 16.04, use:
738
766
 
739
767
  ```yml
740
768
  - name: Install Libsodium
741
- run: sudo apt-get install libsodium18
769
+ run: sudo apt-get update && sudo apt-get install libsodium18
742
770
  ```
743
771
 
744
772
  ##### Travis CI
@@ -89,6 +89,10 @@ module Lockbox
89
89
  module CreateOne
90
90
  def initialize(name, record, attachable)
91
91
  # this won't encrypt existing blobs
92
+ # ideally we'd check metadata for the encrypted flag
93
+ # and disallow unencrypted blobs
94
+ # since they'll raise an error on decryption
95
+ # but earlier versions of Lockbox won't have it
92
96
  attachable = Lockbox::Utils.encrypt_attachable(record, name, attachable) if Lockbox::Utils.encrypted?(record, name) && !attachable.is_a?(ActiveStorage::Blob)
93
97
  super(name, record, attachable)
94
98
  end
@@ -97,4 +97,8 @@ module Lockbox
97
97
  end
98
98
  end
99
99
 
100
+ if CarrierWave::VERSION.to_i > 2
101
+ raise "CarrierWave version not supported in this version of Lockbox: #{CarrierWave::VERSION}"
102
+ end
103
+
100
104
  CarrierWave::Uploader::Base.extend(Lockbox::CarrierWaveExtensions)
@@ -55,6 +55,15 @@ module Lockbox
55
55
  decrypt_method_name = "decrypt_#{encrypted_attribute}"
56
56
 
57
57
  class_eval do
58
+ # Lockbox uses custom inspect
59
+ # but this could be useful for other gems
60
+ if activerecord && ActiveRecord::VERSION::MAJOR >= 6
61
+ # only add virtual attribute
62
+ # need to use regexp since strings do partial matching
63
+ # also, need to use += instead of <<
64
+ self.filter_attributes += [/\A#{Regexp.escape(options[:attribute])}\z/]
65
+ end
66
+
58
67
  @lockbox_attributes ||= {}
59
68
 
60
69
  if @lockbox_attributes.empty?
@@ -79,15 +88,40 @@ module Lockbox
79
88
  super(options)
80
89
  end
81
90
 
82
- # use same approach as devise
91
+ # maintain order
92
+ # replace ciphertext attributes w/ virtual attributes (filtered)
83
93
  def inspect
84
- inspection =
85
- serializable_hash.map do |k,v|
86
- "#{k}: #{respond_to?(:attribute_for_inspect) ? attribute_for_inspect(k) : v.inspect}"
94
+ lockbox_attributes = {}
95
+ lockbox_encrypted_attributes = {}
96
+ self.class.lockbox_attributes.each do |_, lockbox_attribute|
97
+ lockbox_attributes[lockbox_attribute[:attribute]] = true
98
+ lockbox_encrypted_attributes[lockbox_attribute[:encrypted_attribute]] = lockbox_attribute[:attribute]
99
+ end
100
+
101
+ inspection = []
102
+ # use serializable_hash like Devise
103
+ values = serializable_hash
104
+ self.class.attribute_names.each do |k|
105
+ next if !has_attribute?(k) || lockbox_attributes[k]
106
+
107
+ # check for lockbox attribute
108
+ if lockbox_encrypted_attributes[k]
109
+ # check if ciphertext attribute nil to avoid loading attribute
110
+ v = send(k).nil? ? "nil" : "[FILTERED]"
111
+ k = lockbox_encrypted_attributes[k]
112
+ elsif values.key?(k)
113
+ v = respond_to?(:attribute_for_inspect) ? attribute_for_inspect(k) : values[k].inspect
114
+
115
+ # fix for https://github.com/rails/rails/issues/40725
116
+ # TODO only apply to Active Record 6.0
117
+ if respond_to?(:inspection_filter, true) && v != "nil"
118
+ v = inspection_filter.filter_param(k, v)
119
+ end
120
+ else
121
+ next
87
122
  end
88
123
 
89
- self.class.lockbox_attributes.map do |_, lockbox_attribute|
90
- inspection << "#{lockbox_attribute[:attribute]}: [FILTERED]" if has_attribute?(lockbox_attribute[:encrypted_attribute])
124
+ inspection << "#{k}: #{v}"
91
125
  end
92
126
 
93
127
  "#<#{self.class} #{inspection.join(", ")}>"
@@ -352,7 +386,7 @@ module Lockbox
352
386
  table = activerecord ? table_name : collection_name.to_s
353
387
 
354
388
  unless message.nil?
355
- # TODO use attribute type class in 0.6.0
389
+ # TODO use attribute type class in 0.7.0
356
390
  case options[:type]
357
391
  when :boolean
358
392
  message = ActiveRecord::Type::Boolean.new.serialize(message)
@@ -407,7 +441,7 @@ module Lockbox
407
441
  end
408
442
 
409
443
  unless message.nil?
410
- # TODO use attribute type class in 0.6.0
444
+ # TODO use attribute type class in 0.7.0
411
445
  case options[:type]
412
446
  when :boolean
413
447
  message = message == "t"
@@ -93,8 +93,7 @@ module Lockbox
93
93
  end
94
94
 
95
95
  # don't analyze encrypted data
96
- metadata = {"analyzed" => true}
97
- metadata["encrypted"] = true if options[:migrating]
96
+ metadata = {"analyzed" => true, "encrypted" => true}
98
97
  attachable[:metadata] = (attachable[:metadata] || {}).merge(metadata)
99
98
  end
100
99
 
@@ -1,3 +1,3 @@
1
1
  module Lockbox
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lockbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-22 00:00:00.000000000 Z
11
+ date: 2020-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler