lockbox 0.6.0 → 0.6.5

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
  SHA256:
3
- metadata.gz: 77945cdf065bda9282a4a9cbffd77ebe518bcbe11c3e3ccaa91768bd1579f94c
4
- data.tar.gz: ab052f812a91e1620dcc52ac578006b55e84d5aae1770ecb5c6c89c5119f9073
3
+ metadata.gz: c45d2348a69188c159cef722e1bcf20cbb47091d41a18dea9aad623479138f9b
4
+ data.tar.gz: 62aa904c4dadd24e8fa727f8d7d8e966d2f9aac8494c05185ecee6bb1129de5f
5
5
  SHA512:
6
- metadata.gz: 8223d89af7efa1e4192c48512a45177d877df2c1878da425b05bf4e2b066c1f3a413b57f8f0fbdc73a04f000db191bfde2ef8bb0319c4bce7eee6a1985a3771f
7
- data.tar.gz: 7bcb4b647f4abdc8141c571441ce1c8e47b5864aee3e043cd7f620ca7f9abc208ddb1134ac6f35700c73a30f934c56169ff5bca235ba32faba4a0d2325bc926a
6
+ metadata.gz: f65d019fd987015f246fa3fb901ff23047663cce1a09edeca6e1a69e39e06b6442ec74a12057bc1850704414bfd8ca283da55a1990fa130119faba9df01e136f
7
+ data.tar.gz: 98c7b76529683742621eea3e9c16b6cd1666b125720da58e1f3babb79d2e6b717e47de97b7593425d3ae106553d896d720e75a43165a88cd79a92a255a65a223
data/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ ## 0.6.5 (2021-07-07)
2
+
3
+ - Fixed issue with `pluck` extension not loading in some cases
4
+
5
+ ## 0.6.4 (2021-04-05)
6
+
7
+ - Fixed in place changes in callbacks
8
+ - Fixed `[]` method for encrypted attributes
9
+
10
+ ## 0.6.3 (2021-03-30)
11
+
12
+ - Fixed empty arrays and hashes
13
+ - Fixed content type for CarrierWave 2.2.1
14
+
15
+ ## 0.6.2 (2021-02-08)
16
+
17
+ - Added `inet` type
18
+ - Fixed error when `lockbox` key in Rails credentials has a string value
19
+ - Fixed deprecation warning with Active Record 6.1
20
+
21
+ ## 0.6.1 (2020-12-03)
22
+
23
+ - Added integration with Rails credentials
24
+ - Fixed in place changes for Active Record 6.1
25
+ - Fixed error with `content_type` method for CarrierWave < 2
26
+
1
27
  ## 0.6.0 (2020-12-03)
2
28
 
3
29
  - Added `encrypted` flag to Active Storage metadata
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018-2020 Andrew Kane
3
+ Copyright (c) 2018-2021 Andrew Kane
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -27,7 +27,7 @@ Generate a key
27
27
  Lockbox.generate_key
28
28
  ```
29
29
 
30
- Store the key with your other secrets. This is typically Rails credentials or an environment variable ([dotenv](https://github.com/bkeepers/dotenv) is great for this). Be sure to use different keys in development and production. Keys don’t need to be hex-encoded, but it’s often easier to store them this way.
30
+ Store the key with your other secrets. This is typically Rails credentials or an environment variable ([dotenv](https://github.com/bkeepers/dotenv) is great for this). Be sure to use different keys in development and production.
31
31
 
32
32
  Set the following environment variable with your key (you can use this one in development)
33
33
 
@@ -35,10 +35,17 @@ Set the following environment variable with your key (you can use this one in de
35
35
  LOCKBOX_MASTER_KEY=0000000000000000000000000000000000000000000000000000000000000000
36
36
  ```
37
37
 
38
+ or add it to your credentials for each environment (`rails credentials:edit --environment <env>` for Rails 6+)
39
+
40
+ ```yml
41
+ lockbox:
42
+ master_key: "0000000000000000000000000000000000000000000000000000000000000000"
43
+ ```
44
+
38
45
  or create `config/initializers/lockbox.rb` with something like
39
46
 
40
47
  ```ruby
41
- Lockbox.master_key = Rails.application.credentials.lockbox_master_key
48
+ Lockbox.master_key = Rails.application.credentials.lockbox[:master_key]
42
49
  ```
43
50
 
44
51
  Then follow the instructions below for the data you want to encrypt.
@@ -65,7 +72,7 @@ Then follow the instructions below for the data you want to encrypt.
65
72
  Create a migration with:
66
73
 
67
74
  ```ruby
68
- class AddEmailCiphertextToUsers < ActiveRecord::Migration[6.0]
75
+ class AddEmailCiphertextToUsers < ActiveRecord::Migration[6.1]
69
76
  def change
70
77
  add_column :users, :email_ciphertext, :text
71
78
  end
@@ -114,6 +121,7 @@ class User < ApplicationRecord
114
121
  encrypts :properties, type: :json
115
122
  encrypts :settings, type: :hash
116
123
  encrypts :messages, type: :array
124
+ encrypts :ip, type: :inet
117
125
  end
118
126
  ```
119
127
 
@@ -240,7 +248,7 @@ User.decrypt_email_ciphertext(user.email_ciphertext)
240
248
  Create a migration with:
241
249
 
242
250
  ```ruby
243
- class AddBodyCiphertextToRichTexts < ActiveRecord::Migration[6.0]
251
+ class AddBodyCiphertextToRichTexts < ActiveRecord::Migration[6.1]
244
252
  def change
245
253
  add_column :action_text_rich_texts, :body_ciphertext, :text
246
254
  end
@@ -328,9 +336,7 @@ def license
328
336
  end
329
337
  ```
330
338
 
331
- #### Migrating Existing Files [experimental]
332
-
333
- **Note:** This feature is experimental. Please try it in a non-production environment and [share](https://github.com/ankane/lockbox/issues/44) how it goes.
339
+ #### Migrating Existing Files
334
340
 
335
341
  Lockbox makes it easy to encrypt existing files without downtime.
336
342
 
@@ -371,7 +377,7 @@ Encryption is applied to all versions after processing.
371
377
  You can mount the uploader [as normal](https://github.com/carrierwaveuploader/carrierwave#activerecord). With Active Record, this involves creating a migration:
372
378
 
373
379
  ```ruby
374
- class AddLicenseToUsers < ActiveRecord::Migration[6.0]
380
+ class AddLicenseToUsers < ActiveRecord::Migration[6.1]
375
381
  def change
376
382
  add_column :users, :license, :string
377
383
  end
@@ -560,12 +566,10 @@ Update your model:
560
566
 
561
567
  ```ruby
562
568
  class User < ApplicationRecord
563
- encrypts :email, previous_versions: [{key: previous_key}]
569
+ encrypts :email, previous_versions: [{master_key: previous_key}]
564
570
  end
565
571
  ```
566
572
 
567
- Use `master_key` instead of `key` if passing the master key.
568
-
569
573
  To rotate existing records, use:
570
574
 
571
575
  ```ruby
@@ -579,11 +583,9 @@ Once all records are rotated, you can remove `previous_versions` from the model.
579
583
  Update your initializer:
580
584
 
581
585
  ```ruby
582
- Lockbox.encrypts_action_text_body(previous_versions: [{key: previous_key}])
586
+ Lockbox.encrypts_action_text_body(previous_versions: [{master_key: previous_key}])
583
587
  ```
584
588
 
585
- Use `master_key` instead of `key` if passing the master key.
586
-
587
589
  To rotate existing records, use:
588
590
 
589
591
  ```ruby
@@ -598,12 +600,10 @@ Update your model:
598
600
 
599
601
  ```ruby
600
602
  class User < ApplicationRecord
601
- encrypts_attached :license, previous_versions: [{key: previous_key}]
603
+ encrypts_attached :license, previous_versions: [{master_key: previous_key}]
602
604
  end
603
605
  ```
604
606
 
605
- Use `master_key` instead of `key` if passing the master key.
606
-
607
607
  To rotate existing files, use:
608
608
 
609
609
  ```ruby
@@ -620,12 +620,10 @@ Update your model:
620
620
 
621
621
  ```ruby
622
622
  class LicenseUploader < CarrierWave::Uploader::Base
623
- encrypt previous_versions: [{key: previous_key}]
623
+ encrypt previous_versions: [{master_key: previous_key}]
624
624
  end
625
625
  ```
626
626
 
627
- Use `master_key` instead of `key` if passing the master key.
628
-
629
627
  To rotate existing files, use:
630
628
 
631
629
  ```ruby
@@ -700,7 +698,7 @@ This is the default algorithm. It’s:
700
698
 
701
699
  Lockbox uses 256-bit keys.
702
700
 
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 key. Each database field and file uploader use a different key (derived from the master key) to extend this window.
701
+ **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.
704
702
 
705
703
  ### XSalsa20
706
704
 
@@ -989,7 +987,7 @@ lockbox.decrypt(ciphertext, associated_data: "othercontext") # fails
989
987
  You can use `binary` columns for the ciphertext instead of `text` columns.
990
988
 
991
989
  ```ruby
992
- class AddEmailCiphertextToUsers < ActiveRecord::Migration[6.0]
990
+ class AddEmailCiphertextToUsers < ActiveRecord::Migration[6.1]
993
991
  def change
994
992
  add_column :users, :email_ciphertext, :binary
995
993
  end
@@ -1034,7 +1032,7 @@ end
1034
1032
  Create a migration with:
1035
1033
 
1036
1034
  ```ruby
1037
- class MigrateToLockbox < ActiveRecord::Migration[6.0]
1035
+ class MigrateToLockbox < ActiveRecord::Migration[6.1]
1038
1036
  def change
1039
1037
  add_column :users, :name_ciphertext, :text
1040
1038
  add_column :users, :email_ciphertext, :text
@@ -1067,7 +1065,7 @@ end
1067
1065
  Then remove the previous gem from your Gemfile and drop its columns.
1068
1066
 
1069
1067
  ```ruby
1070
- class RemovePreviousEncryptedColumns < ActiveRecord::Migration[6.0]
1068
+ class RemovePreviousEncryptedColumns < ActiveRecord::Migration[6.1]
1071
1069
  def change
1072
1070
  remove_column :users, :encrypted_name, :text
1073
1071
  remove_column :users, :encrypted_name_iv, :text
@@ -1079,12 +1077,29 @@ end
1079
1077
 
1080
1078
  ## Upgrading
1081
1079
 
1080
+ ### 0.6.0
1081
+
1082
+ 0.6.0 adds `encrypted: true` to Active Storage metadata for new files. This field is informational, but if you prefer to add it to existing files, use:
1083
+
1084
+ ```ruby
1085
+ User.with_attached_license.find_each do |user|
1086
+ next unless user.license.attached?
1087
+
1088
+ metadata = user.license.metadata
1089
+ unless metadata["encrypted"]
1090
+ user.license.blob.update!(metadata: metadata.merge("encrypted" => true))
1091
+ end
1092
+ end
1093
+ ```
1094
+
1082
1095
  ### 0.3.6
1083
1096
 
1084
1097
  0.3.6 makes content type detection more reliable for Active Storage. You can check and update the content type of existing files with:
1085
1098
 
1086
1099
  ```ruby
1087
- User.find_each do |user|
1100
+ User.with_attached_license.find_each do |user|
1101
+ next unless user.license.attached?
1102
+
1088
1103
  license = user.license
1089
1104
  content_type = Marcel::MimeType.for(license.download, name: license.filename.to_s)
1090
1105
  if content_type != license.content_type
@@ -16,9 +16,7 @@ module Lockbox
16
16
  end
17
17
 
18
18
  def data_type
19
- # use connection_config instead of connection.adapter
20
- # so database connection isn't needed
21
- case ActiveRecord::Base.connection_config[:adapter].to_s
19
+ case adapter
22
20
  when /postg/i # postgres, postgis
23
21
  "jsonb"
24
22
  when /mysql/i
@@ -27,6 +25,16 @@ module Lockbox
27
25
  "text"
28
26
  end
29
27
  end
28
+
29
+ # use connection_config instead of connection.adapter
30
+ # so database connection isn't needed
31
+ def adapter
32
+ if ActiveRecord::VERSION::STRING.to_f >= 6.1
33
+ ActiveRecord::Base.connection_db_config.adapter.to_s
34
+ else
35
+ ActiveRecord::Base.connection_config[:adapter].to_s
36
+ end
37
+ end
30
38
  end
31
39
  end
32
40
  end
data/lib/lockbox.rb CHANGED
@@ -27,13 +27,22 @@ end
27
27
 
28
28
  if defined?(ActiveSupport.on_load)
29
29
  ActiveSupport.on_load(:active_record) do
30
+ # TODO raise error in 0.7.0
31
+ if ActiveRecord::VERSION::STRING.to_f <= 5.0
32
+ warn "Active Record version (#{ActiveRecord::VERSION::STRING}) not supported in this version of Lockbox (#{Lockbox::VERSION})"
33
+ end
34
+
30
35
  extend Lockbox::Model
31
36
  extend Lockbox::Model::Attached
32
- ActiveRecord::Calculations.prepend Lockbox::Calculations
37
+ # alias_method is private in Ruby < 2.5
38
+ singleton_class.send(:alias_method, :encrypts, :lockbox_encrypts) if ActiveRecord::VERSION::MAJOR < 7
39
+ ActiveRecord::Relation.prepend Lockbox::Calculations
33
40
  end
34
41
 
35
42
  ActiveSupport.on_load(:mongoid) do
36
43
  Mongoid::Document::ClassMethods.include(Lockbox::Model)
44
+ # alias_method is private in Ruby < 2.5
45
+ Mongoid::Document::ClassMethods.send(:alias_method, :encrypts, :lockbox_encrypts)
37
46
  end
38
47
  end
39
48
 
@@ -101,7 +110,7 @@ module Lockbox
101
110
 
102
111
  def self.encrypts_action_text_body(**options)
103
112
  ActiveSupport.on_load(:action_text_rich_text) do
104
- ActionText::RichText.encrypts :body, **options
113
+ ActionText::RichText.lockbox_encrypts :body, **options
105
114
  end
106
115
  end
107
116
  end
@@ -32,9 +32,17 @@ module Lockbox
32
32
  read.bytesize
33
33
  end
34
34
 
35
- # based on CarrierWave::SanitizedFile#mime_magic_content_type
36
35
  def content_type
37
- MimeMagic.by_magic(read).try(:type) || "invalid/invalid"
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
40
+ # based on CarrierWave::SanitizedFile#mime_magic_content_type
41
+ MimeMagic.by_magic(read).try(:type) || "invalid/invalid"
42
+ else
43
+ # uses filename
44
+ super
45
+ end
38
46
  end
39
47
 
40
48
  # disable processing since already processed
@@ -98,7 +106,10 @@ module Lockbox
98
106
  end
99
107
 
100
108
  if CarrierWave::VERSION.to_i > 2
101
- raise "CarrierWave version not supported in this version of Lockbox: #{CarrierWave::VERSION}"
109
+ raise "CarrierWave version (#{CarrierWave::VERSION}) not supported in this version of Lockbox (#{Lockbox::VERSION})"
110
+ elsif CarrierWave::VERSION.to_i < 1
111
+ # TODO raise error in 0.7.0
112
+ warn "CarrierWave version (#{CarrierWave::VERSION}) not supported in this version of Lockbox (#{Lockbox::VERSION})"
102
113
  end
103
114
 
104
115
  CarrierWave::Uploader::Base.extend(Lockbox::CarrierWaveExtensions)
data/lib/lockbox/model.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Lockbox
2
2
  module Model
3
- def encrypts(*attributes, **options)
3
+ def lockbox_encrypts(*attributes, **options)
4
4
  # support objects
5
5
  # case options[:type]
6
6
  # when Date
@@ -22,7 +22,8 @@ module Lockbox
22
22
  # end
23
23
 
24
24
  custom_type = options[:type].respond_to?(:serialize) && options[:type].respond_to?(:deserialize)
25
- raise ArgumentError, "Unknown type: #{options[:type]}" unless custom_type || [nil, :string, :boolean, :date, :datetime, :time, :integer, :float, :binary, :json, :hash, :array].include?(options[:type])
25
+ valid_types = [nil, :string, :boolean, :date, :datetime, :time, :integer, :float, :binary, :json, :hash, :array, :inet]
26
+ raise ArgumentError, "Unknown type: #{options[:type]}" unless custom_type || valid_types.include?(options[:type])
26
27
 
27
28
  activerecord = defined?(ActiveRecord::Base) && self < ActiveRecord::Base
28
29
  raise ArgumentError, "Type not supported yet with Mongoid" if options[:type] && !activerecord
@@ -148,16 +149,38 @@ module Lockbox
148
149
  # needed for in-place modifications
149
150
  # assigned attributes are encrypted on assignment
150
151
  # and then again here
151
- before_save do
152
+ def lockbox_sync_attributes
152
153
  self.class.lockbox_attributes.each do |_, lockbox_attribute|
153
154
  attribute = lockbox_attribute[:attribute]
154
155
 
155
- if attribute_changed_in_place?(attribute)
156
+ if attribute_changed_in_place?(attribute) || (send("#{attribute}_changed?") && !send("#{lockbox_attribute[:encrypted_attribute]}_changed?"))
156
157
  send("#{attribute}=", send(attribute))
157
158
  end
158
159
  end
159
160
  end
160
161
 
162
+ # safety check
163
+ [:_create_record, :_update_record].each do |method_name|
164
+ unless private_method_defined?(method_name) || method_defined?(method_name)
165
+ raise Lockbox::Error, "Expected #{method_name} to be defined. Please report an issue."
166
+ end
167
+ end
168
+
169
+ def _create_record(*)
170
+ lockbox_sync_attributes
171
+ super
172
+ end
173
+
174
+ def _update_record(*)
175
+ lockbox_sync_attributes
176
+ super
177
+ end
178
+
179
+ def [](attr_name)
180
+ send(attr_name) if self.class.lockbox_attributes.any? { |_, la| la[:attribute] == attr_name.to_s }
181
+ super
182
+ end
183
+
161
184
  def update_columns(attributes)
162
185
  return super unless attributes.is_a?(Hash)
163
186
 
@@ -193,8 +216,11 @@ module Lockbox
193
216
  attributes_to_set.each do |k, v|
194
217
  if respond_to?(:write_attribute_without_type_cast, true)
195
218
  write_attribute_without_type_cast(k, v)
196
- else
219
+ elsif respond_to?(:raw_write_attribute, true)
197
220
  raw_write_attribute(k, v)
221
+ else
222
+ @attributes.write_cast_value(k, v)
223
+ clear_attribute_change(k)
198
224
  end
199
225
  end
200
226
 
@@ -247,6 +273,23 @@ module Lockbox
247
273
  else
248
274
  attribute name, :string
249
275
  end
276
+ else
277
+ # hack for Active Record 6.1
278
+ # to set string type after serialize
279
+ # otherwise, type gets set to ActiveModel::Type::Value
280
+ # which always returns false for changed_in_place?
281
+ # earlier versions of Active Record take the previous code path
282
+ if ActiveRecord::VERSION::STRING.to_f >= 7.0 && attributes_to_define_after_schema_loads[name.to_s].first.is_a?(Proc)
283
+ attribute_type = attributes_to_define_after_schema_loads[name.to_s].first.call(nil)
284
+ if attribute_type.is_a?(ActiveRecord::Type::Serialized) && attribute_type.subtype.nil?
285
+ attribute name, ActiveRecord::Type::Serialized.new(ActiveRecord::Type::String.new, attribute_type.coder)
286
+ end
287
+ elsif ActiveRecord::VERSION::STRING.to_f >= 6.1 && attributes_to_define_after_schema_loads[name.to_s].first.is_a?(Proc)
288
+ attribute_type = attributes_to_define_after_schema_loads[name.to_s].first.call
289
+ if attribute_type.is_a?(ActiveRecord::Type::Serialized) && attribute_type.subtype.nil?
290
+ attribute name, ActiveRecord::Type::Serialized.new(ActiveRecord::Type::String.new, attribute_type.coder)
291
+ end
292
+ end
250
293
  end
251
294
 
252
295
  define_method("#{name}_was") do
@@ -358,7 +401,11 @@ module Lockbox
358
401
  # check for this explicitly as a layer of safety
359
402
  if message.nil? || ((message == {} || message == []) && activerecord && @attributes[name.to_s].value_before_type_cast.nil?)
360
403
  ciphertext = send(encrypted_attribute)
361
- message = self.class.send(decrypt_method_name, ciphertext, context: self)
404
+
405
+ # keep original message for empty hashes and arrays
406
+ unless ciphertext.nil?
407
+ message = self.class.send(decrypt_method_name, ciphertext, context: self)
408
+ end
362
409
 
363
410
  if activerecord
364
411
  # set previous attribute so changes populate correctly
@@ -370,8 +417,13 @@ module Lockbox
370
417
  # decrypt method does type casting
371
418
  if respond_to?(:write_attribute_without_type_cast, true)
372
419
  write_attribute_without_type_cast(name.to_s, message) if !@attributes.frozen?
373
- else
420
+ elsif respond_to?(:raw_write_attribute, true)
374
421
  raw_write_attribute(name, message) if !@attributes.frozen?
422
+ else
423
+ if !@attributes.frozen?
424
+ @attributes.write_cast_value(name.to_s, message)
425
+ clear_attribute_change(name)
426
+ end
375
427
  end
376
428
  else
377
429
  instance_variable_set("@#{name}", message)
@@ -414,6 +466,14 @@ module Lockbox
414
466
  message = ActiveRecord::Type::Float.new.serialize(message)
415
467
  # double precision, big endian
416
468
  message = [message].pack("G") unless message.nil?
469
+ when :inet
470
+ unless message.nil?
471
+ ip = message.is_a?(IPAddr) ? message : (IPAddr.new(message) rescue nil)
472
+ # same format as Postgres, with ipv4 padded to 16 bytes
473
+ # family, netmask, ip
474
+ # return nil for invalid IP like Active Record
475
+ message = ip ? [ip.ipv4? ? 0 : 1, ip.prefix, ip.hton].pack("CCa16") : nil
476
+ end
417
477
  when :string, :binary
418
478
  # do nothing
419
479
  # encrypt will convert to binary
@@ -460,6 +520,11 @@ module Lockbox
460
520
  when :binary
461
521
  # do nothing
462
522
  # decrypt returns binary string
523
+ when :inet
524
+ family, prefix, addr = message.unpack("CCa16")
525
+ len = family == 0 ? 4 : 16
526
+ message = IPAddr.new_ntoh(addr.first(len))
527
+ message.prefix = prefix
463
528
  else
464
529
  # use original name for serialized attributes
465
530
  type = (try(:attribute_types) || {})[original_name.to_s]
@@ -1,6 +1,11 @@
1
1
  module Lockbox
2
2
  class Railtie < Rails::Railtie
3
3
  initializer "lockbox" do |app|
4
+ if defined?(Rails.application.credentials)
5
+ # needs to work when lockbox key has a string value
6
+ Lockbox.master_key ||= Rails.application.credentials.try(:lockbox).try(:fetch, :master_key, nil)
7
+ end
8
+
4
9
  require "lockbox/carrier_wave_extensions" if defined?(CarrierWave)
5
10
 
6
11
  if defined?(ActiveStorage)
@@ -14,7 +19,14 @@ module Lockbox
14
19
  ActiveStorage::Attached::Many.prepend(Lockbox::ActiveStorageExtensions::AttachedMany)
15
20
 
16
21
  # use load hooks when possible
17
- if ActiveStorage::VERSION::MAJOR >= 6
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
18
30
  ActiveSupport.on_load(:active_storage_attachment) do
19
31
  include Lockbox::ActiveStorageExtensions::Attachment
20
32
  end
@@ -1,3 +1,3 @@
1
1
  module Lockbox
2
- VERSION = "0.6.0"
2
+ VERSION = "0.6.5"
3
3
  end
metadata CHANGED
@@ -1,199 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lockbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.5
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-12-03 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: carrierwave
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: combustion
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '1.3'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '1.3'
55
- - !ruby/object:Gem::Dependency
56
- name: rails
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: minitest
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '5'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '5'
83
- - !ruby/object:Gem::Dependency
84
- name: rake
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: rbnacl
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '6'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '6'
111
- - !ruby/object:Gem::Dependency
112
- name: sqlite3
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: pg
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: mysql2
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
- - !ruby/object:Gem::Dependency
154
- name: shrine
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- version: '0'
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - ">="
165
- - !ruby/object:Gem::Version
166
- version: '0'
167
- - !ruby/object:Gem::Dependency
168
- name: shrine-mongoid
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - ">="
172
- - !ruby/object:Gem::Version
173
- version: '0'
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - ">="
179
- - !ruby/object:Gem::Version
180
- version: '0'
181
- - !ruby/object:Gem::Dependency
182
- name: benchmark-ips
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - ">="
186
- - !ruby/object:Gem::Version
187
- version: '0'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: '0'
11
+ date: 2021-07-07 00:00:00.000000000 Z
12
+ dependencies: []
195
13
  description:
196
- email: andrew@chartkick.com
14
+ email: andrew@ankane.org
197
15
  executables: []
198
16
  extensions: []
199
17
  extra_rdoc_files: []
@@ -240,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
240
58
  - !ruby/object:Gem::Version
241
59
  version: '0'
242
60
  requirements: []
243
- rubygems_version: 3.1.4
61
+ rubygems_version: 3.2.3
244
62
  signing_key:
245
63
  specification_version: 4
246
64
  summary: Modern encryption for Ruby and Rails