activejsonmodel 0.1.3 → 0.1.6
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/lib/active_json_model/active_record_encrypted_type.rb +26 -15
- data/lib/active_json_model/active_record_type.rb +16 -10
- data/lib/active_json_model/array.rb +35 -3
- data/lib/active_json_model/model.rb +30 -3
- data/lib/active_json_model/version.rb +1 -1
- data/lib/active_json_model.rb +4 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc97da5d920f8d4bd3086c08d7e785867d6aad6d76549ac5d4642d0dc7905269
|
4
|
+
data.tar.gz: be4f3c6d7b7eadee052cc42d7e7b7e3c4df3f7d86d9d673c6ae0c6dcd34f09f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ffe713e2616fff952482e90adab32f709634e6976040f7dd0c43fa34c5db81de5cf0f8f3829f83cfd9d54730618411d9b8003cfe1e415cf51111dc529a990cd
|
7
|
+
data.tar.gz: f28fee77d5d862f8615b146e7526d6593393518988f7ced44f1871914350e429dc0b1c44763674a1c1946f29699efa1bf3b1c114b87891a5133f1ac098a6352c
|
@@ -18,25 +18,29 @@ if Gem.find_files("symmetric-encryption").any? &&
|
|
18
18
|
# end
|
19
19
|
# end
|
20
20
|
#
|
21
|
-
# class
|
21
|
+
# class User < ActiveRecord::Base
|
22
22
|
# attribute :credentials, Credentials.encrypted_attribute_type
|
23
23
|
# end
|
24
|
+
#
|
25
|
+
# Alternatively, the type can be registered ahead of time:
|
26
|
+
#
|
27
|
+
# # config/initializers/types.rb
|
28
|
+
# ActiveRecord::Type.register(:credentials_encrypted_type, Credentials.encrypted_attribute_type)
|
29
|
+
#
|
30
|
+
# Then the custom type can be used as:
|
31
|
+
#
|
32
|
+
# class User < ActiveRecord::Base
|
33
|
+
# attribute :credentials, :credentials_encrypted_type
|
34
|
+
# end
|
35
|
+
#
|
24
36
|
class ActiveRecordEncryptedType < ::ActiveJsonModel::ActiveRecordType
|
25
37
|
def type
|
26
38
|
:string
|
27
39
|
end
|
28
40
|
|
29
|
-
def cast(value)
|
30
|
-
if value.is_a?(@clazz)
|
31
|
-
value
|
32
|
-
elsif value.is_a?(::Array)
|
33
|
-
@clazz.load(value)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
41
|
def deserialize(value)
|
38
42
|
if String === value
|
39
|
-
|
43
|
+
decoded = SymmetricEncryption.decrypt(value, type: :json) rescue nil
|
40
44
|
@clazz.load(decoded)
|
41
45
|
else
|
42
46
|
super
|
@@ -44,11 +48,18 @@ if Gem.find_files("symmetric-encryption").any? &&
|
|
44
48
|
end
|
45
49
|
|
46
50
|
def serialize(value)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
51
|
+
if value.respond_to?(:dump_to_json)
|
52
|
+
SymmetricEncryption.encrypt(
|
53
|
+
value.dump_to_json,
|
54
|
+
random_iv: true,
|
55
|
+
type: :json
|
56
|
+
)
|
57
|
+
elsif ::Hash === value || ::HashWithIndifferentAccess === value || ::Array === value
|
58
|
+
SymmetricEncryption.encrypt(
|
59
|
+
value,
|
60
|
+
random_iv: true,
|
61
|
+
type: :json
|
62
|
+
)
|
52
63
|
else
|
53
64
|
super
|
54
65
|
end
|
@@ -15,10 +15,21 @@ if Gem.find_files("active_record").any?
|
|
15
15
|
# end
|
16
16
|
# end
|
17
17
|
#
|
18
|
-
# class
|
18
|
+
# class User < ActiveRecord::Base
|
19
19
|
# attribute :credentials, Credentials.attribute_type
|
20
20
|
# end
|
21
21
|
#
|
22
|
+
# Alternatively, the type can be registered ahead of time:
|
23
|
+
#
|
24
|
+
# # config/initializers/types.rb
|
25
|
+
# ActiveRecord::Type.register(:credentials_type, Credentials.attribute_type)
|
26
|
+
#
|
27
|
+
# Then the custom type can be used as:
|
28
|
+
#
|
29
|
+
# class User < ActiveRecord::Base
|
30
|
+
# attribute :credentials, :credentials_type
|
31
|
+
# end
|
32
|
+
#
|
22
33
|
# This is based on:
|
23
34
|
# https://jetrockets.pro/blog/rails-5-attributes-api-value-objects-and-jsonb
|
24
35
|
class ActiveRecordType < ::ActiveRecord::Type::Value
|
@@ -39,11 +50,7 @@ if Gem.find_files("active_record").any?
|
|
39
50
|
end
|
40
51
|
|
41
52
|
def cast(value)
|
42
|
-
|
43
|
-
value
|
44
|
-
elsif value.is_a?(::Array)
|
45
|
-
@clazz.load(value)
|
46
|
-
end
|
53
|
+
@clazz.active_json_model_cast(value)
|
47
54
|
end
|
48
55
|
|
49
56
|
def deserialize(value)
|
@@ -56,10 +63,9 @@ if Gem.find_files("active_record").any?
|
|
56
63
|
end
|
57
64
|
|
58
65
|
def serialize(value)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
when Array, Hash
|
66
|
+
if value.respond_to?(:dump_to_json)
|
67
|
+
::ActiveSupport::JSON.encode(value.dump_to_json)
|
68
|
+
elsif ::Hash === value || ::HashWithIndifferentAccess === value || ::Array === value
|
63
69
|
::ActiveSupport::JSON.encode(value)
|
64
70
|
else
|
65
71
|
super
|
@@ -6,7 +6,7 @@ require 'active_support'
|
|
6
6
|
require_relative './json_attribute'
|
7
7
|
require_relative './after_load_callback'
|
8
8
|
|
9
|
-
if
|
9
|
+
if Gem.find_files("active_record").any?
|
10
10
|
require_relative './active_record_type'
|
11
11
|
require_relative './active_record_encrypted_type'
|
12
12
|
end
|
@@ -238,7 +238,11 @@ module ActiveJsonModel
|
|
238
238
|
#
|
239
239
|
# Note that this array_data would be stored as jsonb in the database
|
240
240
|
def attribute_type
|
241
|
-
|
241
|
+
if Gem.find_files("active_record").any?
|
242
|
+
@attribute_type ||= ::ActiveJsonModel::ActiveRecordType.new(self)
|
243
|
+
else
|
244
|
+
raise RuntimeError.new('ActiveRecord must be installed to use attribute_type')
|
245
|
+
end
|
242
246
|
end
|
243
247
|
|
244
248
|
# Allow this model to be used as ActiveRecord attribute type in Rails 5+.
|
@@ -253,7 +257,15 @@ module ActiveJsonModel
|
|
253
257
|
# Note that this array_data would be stored as a string in the database, encrypted using
|
254
258
|
# a symmetric key at the application level.
|
255
259
|
def encrypted_attribute_type
|
256
|
-
|
260
|
+
if Gem.find_files("active_record").any?
|
261
|
+
if Gem.find_files("symmetric-encryption").any?
|
262
|
+
@encrypted_attribute_type ||= ::ActiveJsonModel::ActiveRecordEncryptedType.new(self)
|
263
|
+
else
|
264
|
+
raise RuntimeError.new('symmetric-encryption must be installed to use attribute_type')
|
265
|
+
end
|
266
|
+
else
|
267
|
+
raise RuntimeError.new('active_record must be installed to use attribute_type')
|
268
|
+
end
|
257
269
|
end
|
258
270
|
end
|
259
271
|
|
@@ -605,6 +617,26 @@ module ActiveJsonModel
|
|
605
617
|
end
|
606
618
|
end
|
607
619
|
|
620
|
+
# Convert a value that might already be an instance of this class from underlying data.
|
621
|
+
# Used to delegate potential loading from ActiveRecord attributes
|
622
|
+
#
|
623
|
+
# @param vals either an instance of this model or an array-like object
|
624
|
+
def active_json_model_cast(vals)
|
625
|
+
if vals.is_a?(self)
|
626
|
+
vals
|
627
|
+
elsif vals.is_a?(::Array)
|
628
|
+
if vals.length == 0
|
629
|
+
self.new(values: vals)
|
630
|
+
elsif vals[0].respond_to?(:dump_to_json)
|
631
|
+
self.new(values: vals)
|
632
|
+
else
|
633
|
+
self.load(vals)
|
634
|
+
end
|
635
|
+
elsif vals.nil?
|
636
|
+
self.new(values: [])
|
637
|
+
end
|
638
|
+
end
|
639
|
+
|
608
640
|
# Define a polymorphic factory to choose the concrete class for the list model. Note that because the array_data passed
|
609
641
|
# to the block is an array of models, you must account for what the behavior is if there are no elements.
|
610
642
|
#
|
@@ -5,7 +5,7 @@ require 'json'
|
|
5
5
|
require_relative './json_attribute'
|
6
6
|
require_relative './after_load_callback'
|
7
7
|
|
8
|
-
if
|
8
|
+
if Gem.find_files("active_record").any?
|
9
9
|
require_relative './active_record_type'
|
10
10
|
require_relative './active_record_encrypted_type'
|
11
11
|
end
|
@@ -275,7 +275,11 @@ module ActiveJsonModel
|
|
275
275
|
#
|
276
276
|
# Note that this data would be stored as jsonb in the database
|
277
277
|
def attribute_type
|
278
|
-
|
278
|
+
if Gem.find_files("active_record").any?
|
279
|
+
@attribute_type ||= ::ActiveJsonModel::ActiveRecordType.new(self)
|
280
|
+
else
|
281
|
+
raise RuntimeError.new('ActiveRecord must be installed to use attribute_type')
|
282
|
+
end
|
279
283
|
end
|
280
284
|
|
281
285
|
# Allow this model to be used as ActiveRecord attribute type in Rails 5+.
|
@@ -290,7 +294,15 @@ module ActiveJsonModel
|
|
290
294
|
# Note that this data would be stored as a string in the database, encrypted using
|
291
295
|
# a symmetric key at the application level.
|
292
296
|
def encrypted_attribute_type
|
293
|
-
|
297
|
+
if Gem.find_files("active_record").any?
|
298
|
+
if Gem.find_files("symmetric-encryption").any?
|
299
|
+
@encrypted_attribute_type ||= ::ActiveJsonModel::ActiveRecordEncryptedType.new(self)
|
300
|
+
else
|
301
|
+
raise RuntimeError.new('symmetric-encryption must be installed to use attribute_type')
|
302
|
+
end
|
303
|
+
else
|
304
|
+
raise RuntimeError.new('active_record must be installed to use attribute_type')
|
305
|
+
end
|
294
306
|
end
|
295
307
|
end
|
296
308
|
|
@@ -547,6 +559,21 @@ module ActiveJsonModel
|
|
547
559
|
end
|
548
560
|
end
|
549
561
|
|
562
|
+
# Convert a value that might already be an instance of this class from underlying data.
|
563
|
+
# Used to delegate potential loading from ActiveRecord attributes
|
564
|
+
#
|
565
|
+
# @param val either an instance of this model or a Hash like object
|
566
|
+
def active_json_model_cast(val)
|
567
|
+
# For polymorphic objects, it's possible that there won't be
|
568
|
+
# a base-class relationship, so just assume that if the
|
569
|
+
# object is an ActiveJsonModel object, it's good.
|
570
|
+
if val.respond_to?(:dump_to_json)
|
571
|
+
val
|
572
|
+
elsif val.is_a?(::Hash) || val.is_a?(::HashWithIndifferentAccess)
|
573
|
+
self.load(val)
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
550
577
|
# Register a new after load callback which is invoked after the instance is loaded from JSON
|
551
578
|
#
|
552
579
|
# @param method_name [Symbol, String] the name of the method to be invoked
|
data/lib/active_json_model.rb
CHANGED
@@ -4,8 +4,10 @@ require "active_support"
|
|
4
4
|
module ActiveJsonModel
|
5
5
|
extend ActiveSupport::Autoload
|
6
6
|
|
7
|
-
autoload :
|
8
|
-
autoload :
|
7
|
+
autoload :ActiveRecordEncryptedType, "active_json_model/active_record_encrypted_type" unless Gem.find_files("active_record").none? || Gem.find_files("symmetric-encryption").none?
|
8
|
+
autoload :ActiveRecordType, "active_json_model/active_record_type" unless Gem.find_files("active_record").none?
|
9
9
|
autoload :Array, "active_json_model/array"
|
10
|
+
autoload :Model, "active_json_model/model"
|
10
11
|
autoload :Utils, "active_json_model/utils"
|
12
|
+
autoload :VERSION, "active_json_model/version"
|
11
13
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activejsonmodel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Morlok
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-09-
|
11
|
+
date: 2022-09-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|