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