dumped_railers 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: 449991bfd3b66c55b2892fb55ba182ef4c6dfcfff70a5a2e91ca866b4482adfe
4
- data.tar.gz: 680b841f7540bf6ff56b786109bde4212f71383ff6cb1147a156a76a832e6710
3
+ metadata.gz: c311dc2cc95619422567711140304a43f5e2851c1028a4c0f468b5f3ffdbe442
4
+ data.tar.gz: 1ea70f2788cfffda44f18433b36dd13302925f60c6894a3e628f264bc5d0161a
5
5
  SHA512:
6
- metadata.gz: 8ba925ee06f3769d74e93cf20b508a01fb8cf1809792525b8f2b506c8c726187223b1b1977f015060daef6bd6fe54b309cbf64df812b143422c6133f10f3ca24
7
- data.tar.gz: ba3bc362b0642c5c77b2a931ac5b32bf134ff841fd3bee868e21df1a2343b7249252f64234185664223311a2156ce87c2b679aa73975f88370ebf2795ed18dff
6
+ metadata.gz: cf2063fe3780b8a203d4131ed1a9d483c2497fe8ceacfa9e741358bcad6015857c404a8e4fd6ff105a63a71565cb596a447acbe6416c3dacf0def55d28b3e676
7
+ data.tar.gz: 0bf0d6f4ead5b7400d8dab700d3491804be5c526dbeab073569e241746029498b65bdd3c49a691ae2ad6d388d27221a507d75a3e069dc625d02d66dcf9bcbd23
data/CHANGELOG.md CHANGED
@@ -62,3 +62,9 @@
62
62
  ### Changed
63
63
  - require std gems (e.g. ostruct, forwardable). Users of dumped_railers are no longer need to require them.
64
64
  - Added CI support against Ruby 3.3, 3.2, together with Rails 7.x, while dropping Ruby < 3.2, Rails < 6.1
65
+
66
+ ## [0.6.0]
67
+ ### Added
68
+ - Add new options to explicitly allow specific classes for YAML import.
69
+ ### Changed
70
+ - Accept Date, Time, DateTIme together with the classes that are set as ActiveRecord.yaml_column_permitted_classes be default.
data/README.md CHANGED
@@ -175,6 +175,48 @@ DumpedRailers.import!(fixture_path, before_save: before_callback, after_save: [a
175
175
 
176
176
  `before_save` / `after_save` can accept both single and multiple (array) arguments.
177
177
 
178
+ ### Deserializing Custom Classes with YAML
179
+
180
+ * YAML (Psych) does not permit to load random class objects for [security reasons](https://discuss.rubyonrails.org/t/cve-2022-32224-possible-rce-escalation-bug-with-serialized-columns-in-active-record/81017).
181
+ * By default, DumpedRailers handles all the objects that Rails permitts (i.e. [ActiveRecord.yaml_column_permitted_classes](https://guides.rubyonrails.org/configuring.html#config-active-record-yaml-column-permitted-classes)), plus Time, Date, and DateTime.
182
+ * DumpedRailers raises `Psych::DisallowedClass` error when non-permitted classes are detected. If you want DumpedRailsers handle other classes, you could specify `yaml_column_permitted_classes` option with configurations or import method's arguments.
183
+ * *Please use this option with extra care* for security - again, it is recommended to use this for development purpose only.
184
+
185
+ ```ruby
186
+ DumpedRailers.configure do |config|
187
+ config.ignorable_columns += [:published_on] # :published_on will be ignored *on top of* default settings.
188
+ end
189
+ ```
190
+
191
+ #### Caveats
192
+ * If you wish to load Date, Time object, it would be easier to load it as a string. DumpedRailers will pass it to the specified ActiveRecord models and they typecast the raw string into the appropreate date/time object.
193
+
194
+ * below columns (published_date, published_time, first_drafted_at) all will be passed as a string (as the value is surrounded by the quotes). Strings will be interperted to apropreate column type with ActiveRecord.
195
+
196
+ ```ruby
197
+ _fixture:
198
+ model_class: Article
199
+ fixture_generated_by: DumpedRailers
200
+ __article_1:
201
+ title: Harry Potter
202
+ published_date: '2024-03-01'
203
+ published_time: '10:00:00'
204
+ first_drafted_at: '2024-02-01T10:10:10+09:00'
205
+ ```
206
+
207
+ * below fixture (without quotes) will be directly interperted to Date or Time via YAML module. It needs to have proper format that YAML can interpret.
208
+
209
+ ```ruby
210
+ _fixture:
211
+ model_class: Article
212
+ fixture_generated_by: DumpedRailers
213
+ __article_1:
214
+ title: Harry Potter
215
+ published_date: 2024-03-01
216
+ published_time: 2000-01-01 10:00:00
217
+ first_drafted_at: 2024-02-01T10:10:10+09:00
218
+ ```
219
+
178
220
  ### Configuration
179
221
 
180
222
  * All the settings can be configured by either configuration (global) or arguments (at runtime).
@@ -5,7 +5,7 @@ require 'ostruct'
5
5
  module DumpedRailers
6
6
  module Configuration
7
7
  extend Forwardable
8
- def_delegators :@_config, :preprocessors, :ignorable_columns, :authorized_models
8
+ def_delegators :@_config, :preprocessors, :ignorable_columns, :authorized_models, :yaml_column_permitted_classes
9
9
 
10
10
  def configure
11
11
  yield config
@@ -17,10 +17,20 @@ module DumpedRailers
17
17
 
18
18
  IGNORABLE_COLUMNS = %w[id created_at updated_at]
19
19
  def configure_defaults!
20
+ default_yaml_column_permitted_classes =
21
+ # FIXME: this will be no longer needed when we drop support for older Rails versions
22
+ # https://discuss.rubyonrails.org/t/cve-2022-32224-possible-rce-escalation-bug-with-serialized-columns-in-active-record/81017
23
+ if ActiveRecord.respond_to?(:yaml_column_permitted_classes)
24
+ ActiveRecord.yaml_column_permitted_classes + [Date, Time, DateTime]
25
+ else
26
+ [Date, Time, DateTime]
27
+ end
28
+
20
29
  clear_configuration!(
21
30
  ignorable_columns: IGNORABLE_COLUMNS,
22
- preprocessors: [],
31
+ preprocessors: [],
23
32
  authorized_models: :any,
33
+ yaml_column_permitted_classes: default_yaml_column_permitted_classes,
24
34
  )
25
35
  end
26
36
 
@@ -5,7 +5,7 @@ require "yaml"
5
5
  module DumpedRailers
6
6
  module FileHelper
7
7
  class << self
8
- def read_fixtures(*paths)
8
+ def read_fixtures(*paths, yaml_column_permitted_classes: [])
9
9
  yaml_files = paths.flat_map { |path|
10
10
  if File.file?(path)
11
11
  path
@@ -18,7 +18,7 @@ module DumpedRailers
18
18
 
19
19
  yaml_files.map { |file|
20
20
  raw_data = ::File.read(file)
21
- YAML.load(raw_data)
21
+ YAML.safe_load(raw_data, permitted_classes: yaml_column_permitted_classes)
22
22
  }
23
23
  end
24
24
 
@@ -6,14 +6,14 @@ module DumpedRailers
6
6
  class Import
7
7
  attr_reader :fixture_set
8
8
 
9
- def initialize(*paths, authorized_models: [], before_save: [], after_save: [])
9
+ def initialize(*paths, authorized_models: [], before_save: [], after_save: [], yaml_column_permitted_classes: [])
10
10
  @before_save = before_save
11
11
  @after_save = after_save
12
12
 
13
13
  if (paths.first.is_a? Hash)
14
14
  @raw_fixtures = paths.first.values
15
15
  else
16
- @raw_fixtures = FileHelper.read_fixtures(*paths)
16
+ @raw_fixtures = FileHelper.read_fixtures(*paths, yaml_column_permitted_classes: yaml_column_permitted_classes)
17
17
  end
18
18
 
19
19
  @fixture_set = RecordBuilder::FixtureSet.new(@raw_fixtures, authorized_models: authorized_models)
@@ -1,3 +1,3 @@
1
1
  module DumpedRailers
2
- VERSION = '0.5.0'
2
+ VERSION = '0.6.0'
3
3
  end
@@ -24,13 +24,19 @@ module DumpedRailers
24
24
  fixtures
25
25
  end
26
26
 
27
- def import!(*paths, authorized_models: nil, before_save: nil, after_save: nil)
27
+ def import!(*paths, authorized_models: nil, before_save: nil, after_save: nil, yaml_column_permitted_classes: [])
28
28
  # make sure class-baseed caches starts with clean state
29
29
  DumpedRailers::RecordBuilder::FixtureRow::RecordStore.clear!
30
30
  DumpedRailers::RecordBuilder::DependencyTracker.clear!
31
31
 
32
32
  # override global config settings when options are specified
33
- runtime_options = { authorized_models: authorized_models.presence }.compact.reverse_merge(import_options)
33
+ runtime_options =
34
+ {
35
+ authorized_models: authorized_models.presence,
36
+ yaml_column_permitted_classes: yaml_column_permitted_classes.presence,
37
+ }
38
+ .compact
39
+ .reverse_merge(import_options)
34
40
 
35
41
  before_save = Array(before_save).compact
36
42
  after_save = Array(after_save).compact
@@ -40,6 +46,7 @@ module DumpedRailers
40
46
  authorized_models: runtime_options[:authorized_models],
41
47
  before_save: before_save,
42
48
  after_save: after_save,
49
+ yaml_column_permitted_classes: runtime_options[:yaml_column_permitted_classes]
43
50
  )
44
51
  fixture_handler.import_all!
45
52
  end
@@ -55,7 +62,7 @@ module DumpedRailers
55
62
  end
56
63
 
57
64
  def import_options
58
- options.slice(:authorized_models)
65
+ options.slice(:authorized_models, :yaml_column_permitted_classes)
59
66
  end
60
67
  end
61
68
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dumped_railers
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
  - Koji Onishi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-09-04 00:00:00.000000000 Z
11
+ date: 2024-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler