lockbox 0.6.2 → 0.6.3
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 +6 -1
- data/README.md +11 -19
- data/lib/lockbox/carrier_wave_extensions.rb +4 -1
- data/lib/lockbox/model.rb +21 -4
- data/lib/lockbox/railtie.rb +8 -1
- data/lib/lockbox/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbcd16c017fd2282888d124ab9d82029b92405bdaca39034ab4e52ee5eb92010
|
4
|
+
data.tar.gz: a54398f0e0acbd1543be296b4ca0214a3b6ca120dc5d89a5f488ac160309ea6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1487a899e37749915555456b59ddb23b75bdc95ce8d8598750e13873c1226de7b7183d3306cfef3e3190ec52275ad452c25ac7c1aab7585a05630c1d312268c
|
7
|
+
data.tar.gz: 4686137e29c935e5f7f141c8239332f89d14764a94a70ee6160f138aa29cc1ce496a0fe384965c0d77ba795700fb58a4ed86feabf5318e25434b86ee0df47153
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -72,7 +72,7 @@ Then follow the instructions below for the data you want to encrypt.
|
|
72
72
|
Create a migration with:
|
73
73
|
|
74
74
|
```ruby
|
75
|
-
class AddEmailCiphertextToUsers < ActiveRecord::Migration[6.
|
75
|
+
class AddEmailCiphertextToUsers < ActiveRecord::Migration[6.1]
|
76
76
|
def change
|
77
77
|
add_column :users, :email_ciphertext, :text
|
78
78
|
end
|
@@ -248,7 +248,7 @@ User.decrypt_email_ciphertext(user.email_ciphertext)
|
|
248
248
|
Create a migration with:
|
249
249
|
|
250
250
|
```ruby
|
251
|
-
class AddBodyCiphertextToRichTexts < ActiveRecord::Migration[6.
|
251
|
+
class AddBodyCiphertextToRichTexts < ActiveRecord::Migration[6.1]
|
252
252
|
def change
|
253
253
|
add_column :action_text_rich_texts, :body_ciphertext, :text
|
254
254
|
end
|
@@ -379,7 +379,7 @@ Encryption is applied to all versions after processing.
|
|
379
379
|
You can mount the uploader [as normal](https://github.com/carrierwaveuploader/carrierwave#activerecord). With Active Record, this involves creating a migration:
|
380
380
|
|
381
381
|
```ruby
|
382
|
-
class AddLicenseToUsers < ActiveRecord::Migration[6.
|
382
|
+
class AddLicenseToUsers < ActiveRecord::Migration[6.1]
|
383
383
|
def change
|
384
384
|
add_column :users, :license, :string
|
385
385
|
end
|
@@ -568,12 +568,10 @@ Update your model:
|
|
568
568
|
|
569
569
|
```ruby
|
570
570
|
class User < ApplicationRecord
|
571
|
-
encrypts :email, previous_versions: [{
|
571
|
+
encrypts :email, previous_versions: [{master_key: previous_key}]
|
572
572
|
end
|
573
573
|
```
|
574
574
|
|
575
|
-
Use `master_key` instead of `key` if passing the master key.
|
576
|
-
|
577
575
|
To rotate existing records, use:
|
578
576
|
|
579
577
|
```ruby
|
@@ -587,11 +585,9 @@ Once all records are rotated, you can remove `previous_versions` from the model.
|
|
587
585
|
Update your initializer:
|
588
586
|
|
589
587
|
```ruby
|
590
|
-
Lockbox.encrypts_action_text_body(previous_versions: [{
|
588
|
+
Lockbox.encrypts_action_text_body(previous_versions: [{master_key: previous_key}])
|
591
589
|
```
|
592
590
|
|
593
|
-
Use `master_key` instead of `key` if passing the master key.
|
594
|
-
|
595
591
|
To rotate existing records, use:
|
596
592
|
|
597
593
|
```ruby
|
@@ -606,12 +602,10 @@ Update your model:
|
|
606
602
|
|
607
603
|
```ruby
|
608
604
|
class User < ApplicationRecord
|
609
|
-
encrypts_attached :license, previous_versions: [{
|
605
|
+
encrypts_attached :license, previous_versions: [{master_key: previous_key}]
|
610
606
|
end
|
611
607
|
```
|
612
608
|
|
613
|
-
Use `master_key` instead of `key` if passing the master key.
|
614
|
-
|
615
609
|
To rotate existing files, use:
|
616
610
|
|
617
611
|
```ruby
|
@@ -628,12 +622,10 @@ Update your model:
|
|
628
622
|
|
629
623
|
```ruby
|
630
624
|
class LicenseUploader < CarrierWave::Uploader::Base
|
631
|
-
encrypt previous_versions: [{
|
625
|
+
encrypt previous_versions: [{master_key: previous_key}]
|
632
626
|
end
|
633
627
|
```
|
634
628
|
|
635
|
-
Use `master_key` instead of `key` if passing the master key.
|
636
|
-
|
637
629
|
To rotate existing files, use:
|
638
630
|
|
639
631
|
```ruby
|
@@ -708,7 +700,7 @@ This is the default algorithm. It’s:
|
|
708
700
|
|
709
701
|
Lockbox uses 256-bit keys.
|
710
702
|
|
711
|
-
**For users who do a lot of encryptions:** You should rotate an individual key after 2 billion encryptions to minimize the chance of a [nonce collision](https://www.cryptologie.net/article/402/is-symmetric-security-solved/), which will expose the key. Each database field and file uploader use a different key (derived from the master key) to extend this window.
|
703
|
+
**For users who do a lot of encryptions:** You should rotate an individual key after 2 billion encryptions to minimize the chance of a [nonce collision](https://www.cryptologie.net/article/402/is-symmetric-security-solved/), which will expose the authentication key. Each database field and file uploader use a different key (derived from the master key) to extend this window.
|
712
704
|
|
713
705
|
### XSalsa20
|
714
706
|
|
@@ -997,7 +989,7 @@ lockbox.decrypt(ciphertext, associated_data: "othercontext") # fails
|
|
997
989
|
You can use `binary` columns for the ciphertext instead of `text` columns.
|
998
990
|
|
999
991
|
```ruby
|
1000
|
-
class AddEmailCiphertextToUsers < ActiveRecord::Migration[6.
|
992
|
+
class AddEmailCiphertextToUsers < ActiveRecord::Migration[6.1]
|
1001
993
|
def change
|
1002
994
|
add_column :users, :email_ciphertext, :binary
|
1003
995
|
end
|
@@ -1042,7 +1034,7 @@ end
|
|
1042
1034
|
Create a migration with:
|
1043
1035
|
|
1044
1036
|
```ruby
|
1045
|
-
class MigrateToLockbox < ActiveRecord::Migration[6.
|
1037
|
+
class MigrateToLockbox < ActiveRecord::Migration[6.1]
|
1046
1038
|
def change
|
1047
1039
|
add_column :users, :name_ciphertext, :text
|
1048
1040
|
add_column :users, :email_ciphertext, :text
|
@@ -1075,7 +1067,7 @@ end
|
|
1075
1067
|
Then remove the previous gem from your Gemfile and drop its columns.
|
1076
1068
|
|
1077
1069
|
```ruby
|
1078
|
-
class RemovePreviousEncryptedColumns < ActiveRecord::Migration[6.
|
1070
|
+
class RemovePreviousEncryptedColumns < ActiveRecord::Migration[6.1]
|
1079
1071
|
def change
|
1080
1072
|
remove_column :users, :encrypted_name, :text
|
1081
1073
|
remove_column :users, :encrypted_name_iv, :text
|
@@ -33,7 +33,10 @@ module Lockbox
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def content_type
|
36
|
-
if CarrierWave::VERSION
|
36
|
+
if Gem::Version.new(CarrierWave::VERSION) >= Gem::Version.new("2.2.1")
|
37
|
+
# based on CarrierWave::SanitizedFile#marcel_magic_content_type
|
38
|
+
Marcel::Magic.by_magic(read).try(:type) || "invalid/invalid"
|
39
|
+
elsif CarrierWave::VERSION.to_i >= 2
|
37
40
|
# based on CarrierWave::SanitizedFile#mime_magic_content_type
|
38
41
|
MimeMagic.by_magic(read).try(:type) || "invalid/invalid"
|
39
42
|
else
|
data/lib/lockbox/model.rb
CHANGED
@@ -194,8 +194,11 @@ module Lockbox
|
|
194
194
|
attributes_to_set.each do |k, v|
|
195
195
|
if respond_to?(:write_attribute_without_type_cast, true)
|
196
196
|
write_attribute_without_type_cast(k, v)
|
197
|
-
|
197
|
+
elsif respond_to?(:raw_write_attribute, true)
|
198
198
|
raw_write_attribute(k, v)
|
199
|
+
else
|
200
|
+
@attributes.write_cast_value(k, v)
|
201
|
+
clear_attribute_change(k)
|
199
202
|
end
|
200
203
|
end
|
201
204
|
|
@@ -254,7 +257,12 @@ module Lockbox
|
|
254
257
|
# otherwise, type gets set to ActiveModel::Type::Value
|
255
258
|
# which always returns false for changed_in_place?
|
256
259
|
# earlier versions of Active Record take the previous code path
|
257
|
-
if ActiveRecord::VERSION::STRING.to_f >=
|
260
|
+
if ActiveRecord::VERSION::STRING.to_f >= 7.0 && attributes_to_define_after_schema_loads[name.to_s].first.is_a?(Proc)
|
261
|
+
attribute_type = attributes_to_define_after_schema_loads[name.to_s].first.call(nil)
|
262
|
+
if attribute_type.is_a?(ActiveRecord::Type::Serialized) && attribute_type.subtype.nil?
|
263
|
+
attribute name, ActiveRecord::Type::Serialized.new(ActiveRecord::Type::String.new, attribute_type.coder)
|
264
|
+
end
|
265
|
+
elsif ActiveRecord::VERSION::STRING.to_f >= 6.1 && attributes_to_define_after_schema_loads[name.to_s].first.is_a?(Proc)
|
258
266
|
attribute_type = attributes_to_define_after_schema_loads[name.to_s].first.call
|
259
267
|
if attribute_type.is_a?(ActiveRecord::Type::Serialized) && attribute_type.subtype.nil?
|
260
268
|
attribute name, ActiveRecord::Type::Serialized.new(ActiveRecord::Type::String.new, attribute_type.coder)
|
@@ -371,7 +379,11 @@ module Lockbox
|
|
371
379
|
# check for this explicitly as a layer of safety
|
372
380
|
if message.nil? || ((message == {} || message == []) && activerecord && @attributes[name.to_s].value_before_type_cast.nil?)
|
373
381
|
ciphertext = send(encrypted_attribute)
|
374
|
-
|
382
|
+
|
383
|
+
# keep original message for empty hashes and arrays
|
384
|
+
unless ciphertext.nil?
|
385
|
+
message = self.class.send(decrypt_method_name, ciphertext, context: self)
|
386
|
+
end
|
375
387
|
|
376
388
|
if activerecord
|
377
389
|
# set previous attribute so changes populate correctly
|
@@ -383,8 +395,13 @@ module Lockbox
|
|
383
395
|
# decrypt method does type casting
|
384
396
|
if respond_to?(:write_attribute_without_type_cast, true)
|
385
397
|
write_attribute_without_type_cast(name.to_s, message) if !@attributes.frozen?
|
386
|
-
|
398
|
+
elsif respond_to?(:raw_write_attribute, true)
|
387
399
|
raw_write_attribute(name, message) if !@attributes.frozen?
|
400
|
+
else
|
401
|
+
if !@attributes.frozen?
|
402
|
+
@attributes.write_cast_value(name.to_s, message)
|
403
|
+
clear_attribute_change(name)
|
404
|
+
end
|
388
405
|
end
|
389
406
|
else
|
390
407
|
instance_variable_set("@#{name}", message)
|
data/lib/lockbox/railtie.rb
CHANGED
@@ -19,7 +19,14 @@ module Lockbox
|
|
19
19
|
ActiveStorage::Attached::Many.prepend(Lockbox::ActiveStorageExtensions::AttachedMany)
|
20
20
|
|
21
21
|
# use load hooks when possible
|
22
|
-
if ActiveStorage::VERSION::MAJOR >=
|
22
|
+
if ActiveStorage::VERSION::MAJOR >= 7
|
23
|
+
ActiveSupport.on_load(:active_storage_attachment) do
|
24
|
+
prepend Lockbox::ActiveStorageExtensions::Attachment
|
25
|
+
end
|
26
|
+
ActiveSupport.on_load(:active_storage_blob) do
|
27
|
+
prepend Lockbox::ActiveStorageExtensions::Blob
|
28
|
+
end
|
29
|
+
elsif ActiveStorage::VERSION::MAJOR >= 6
|
23
30
|
ActiveSupport.on_load(:active_storage_attachment) do
|
24
31
|
include Lockbox::ActiveStorageExtensions::Attachment
|
25
32
|
end
|
data/lib/lockbox/version.rb
CHANGED
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.6.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: andrew@ankane.org
|
@@ -58,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
58
58
|
- !ruby/object:Gem::Version
|
59
59
|
version: '0'
|
60
60
|
requirements: []
|
61
|
-
rubygems_version: 3.
|
61
|
+
rubygems_version: 3.0.3
|
62
62
|
signing_key:
|
63
63
|
specification_version: 4
|
64
64
|
summary: Modern encryption for Ruby and Rails
|