activestorage 6.1.3.2 → 6.1.4.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activestorage might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +70 -0
- data/app/controllers/active_storage/representations/base_controller.rb +14 -0
- data/app/controllers/active_storage/representations/proxy_controller.rb +3 -9
- data/app/controllers/active_storage/representations/redirect_controller.rb +2 -4
- data/app/models/active_storage/blob/representable.rb +1 -1
- data/app/models/active_storage/blob.rb +1 -1
- data/app/models/active_storage/variant.rb +1 -1
- data/app/models/active_storage/variant_with_record.rb +1 -1
- data/lib/active_storage/engine.rb +18 -0
- data/lib/active_storage/errors.rb +3 -0
- data/lib/active_storage/gem_version.rb +2 -2
- data/lib/active_storage/previewer/video_previewer.rb +1 -1
- data/lib/active_storage/previewer.rb +10 -1
- data/lib/active_storage/transformers/image_processing_transformer.rb +352 -0
- data/lib/active_storage.rb +5 -0
- data/lib/tasks/activestorage.rake +5 -1
- metadata +19 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78649b7f2ca40b322750c583e72493acf680a1b7f32bb2c8a1e20eb69ebd1df8
|
4
|
+
data.tar.gz: fe790afaf918cb57fedbfac741cb3f6baeed0e62a6cbb3854568ab1b8a1ab126
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e94e94a8f3b462d223a930446344d9f315de7881be67b841f45cecafb4ae11895308dea426a4b073dd8d9495ed6eda7ad53b9051d8c2ba1a24ec40319069ab3
|
7
|
+
data.tar.gz: 527abfc288dfa20d5e24224bc50580f0f2b65f2e5273be729b914976a5cb649dadfab7428bc0a6eac0aa76e331bd6a10b6002f7d0e1a17a60f1741e259749904
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,73 @@
|
|
1
|
+
## Rails 6.1.4.7 (March 08, 2022) ##
|
2
|
+
|
3
|
+
* Added image transformation validation via configurable allow-list.
|
4
|
+
|
5
|
+
Variant now offers a configurable allow-list for
|
6
|
+
transformation methods in addition to a configurable deny-list for arguments.
|
7
|
+
|
8
|
+
[CVE-2022-21831]
|
9
|
+
|
10
|
+
|
11
|
+
## Rails 6.1.4.6 (February 11, 2022) ##
|
12
|
+
|
13
|
+
* No changes.
|
14
|
+
|
15
|
+
|
16
|
+
## Rails 6.1.4.5 (February 11, 2022) ##
|
17
|
+
|
18
|
+
* No changes.
|
19
|
+
|
20
|
+
|
21
|
+
## Rails 6.1.4.4 (December 15, 2021) ##
|
22
|
+
|
23
|
+
* No changes.
|
24
|
+
|
25
|
+
|
26
|
+
## Rails 6.1.4.3 (December 14, 2021) ##
|
27
|
+
|
28
|
+
* No changes.
|
29
|
+
|
30
|
+
|
31
|
+
## Rails 6.1.4.2 (December 14, 2021) ##
|
32
|
+
|
33
|
+
* No changes.
|
34
|
+
|
35
|
+
|
36
|
+
## Rails 6.1.4.1 (August 19, 2021) ##
|
37
|
+
|
38
|
+
* No changes.
|
39
|
+
|
40
|
+
|
41
|
+
## Rails 6.1.4 (June 24, 2021) ##
|
42
|
+
|
43
|
+
* The parameters sent to `ffmpeg` for generating a video preview image are now
|
44
|
+
configurable under `config.active_storage.video_preview_arguments`.
|
45
|
+
|
46
|
+
*Brendon Muir*
|
47
|
+
|
48
|
+
* Fix Active Storage update task when running in an engine.
|
49
|
+
|
50
|
+
Justin Malčić*
|
51
|
+
|
52
|
+
* Don't raise an error if the mime type is not recognized.
|
53
|
+
|
54
|
+
Fixes #41777.
|
55
|
+
|
56
|
+
*Alex Ghiculescu*
|
57
|
+
|
58
|
+
* `ActiveStorage::PreviewError` is raised when a previewer is unable to generate a preview image.
|
59
|
+
|
60
|
+
*Alex Robbin*
|
61
|
+
|
62
|
+
* respond with 404 given invalid variation key when asking for representations.
|
63
|
+
|
64
|
+
*George Claghorn*
|
65
|
+
|
66
|
+
* `Blob` creation shouldn't crash if no service selected.
|
67
|
+
|
68
|
+
*Alex Ghiculescu*
|
69
|
+
|
70
|
+
|
1
71
|
## Rails 6.1.3.2 (May 05, 2021) ##
|
2
72
|
|
3
73
|
* No changes.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ActiveStorage::Representations::BaseController < ActiveStorage::BaseController #:nodoc:
|
4
|
+
include ActiveStorage::SetBlob
|
5
|
+
|
6
|
+
before_action :set_representation
|
7
|
+
|
8
|
+
private
|
9
|
+
def set_representation
|
10
|
+
@representation = @blob.representation(params[:variation_key]).processed
|
11
|
+
rescue ActiveSupport::MessageVerifier::InvalidSignature
|
12
|
+
head :not_found
|
13
|
+
end
|
14
|
+
end
|
@@ -1,19 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Proxy files through application. This avoids having a redirect and makes files easier to cache.
|
4
|
-
class ActiveStorage::Representations::ProxyController < ActiveStorage::BaseController
|
5
|
-
include ActiveStorage::SetBlob
|
4
|
+
class ActiveStorage::Representations::ProxyController < ActiveStorage::Representations::BaseController
|
6
5
|
include ActiveStorage::SetHeaders
|
7
6
|
|
8
7
|
def show
|
9
8
|
http_cache_forever public: true do
|
10
|
-
set_content_headers_from representation.image
|
11
|
-
stream representation
|
9
|
+
set_content_headers_from @representation.image
|
10
|
+
stream @representation
|
12
11
|
end
|
13
12
|
end
|
14
|
-
|
15
|
-
private
|
16
|
-
def representation
|
17
|
-
@representation ||= @blob.representation(params[:variation_key]).processed
|
18
|
-
end
|
19
13
|
end
|
@@ -4,11 +4,9 @@
|
|
4
4
|
# Note: These URLs are publicly accessible. If you need to enforce access protection beyond the
|
5
5
|
# security-through-obscurity factor of the signed blob and variation reference, you'll need to implement your own
|
6
6
|
# authenticated redirection controller.
|
7
|
-
class ActiveStorage::Representations::RedirectController < ActiveStorage::BaseController
|
8
|
-
include ActiveStorage::SetBlob
|
9
|
-
|
7
|
+
class ActiveStorage::Representations::RedirectController < ActiveStorage::Representations::BaseController
|
10
8
|
def show
|
11
9
|
expires_in ActiveStorage.service_urls_expire_in
|
12
|
-
redirect_to @
|
10
|
+
redirect_to @representation.url(disposition: params[:disposition])
|
13
11
|
end
|
14
12
|
end
|
@@ -113,7 +113,7 @@ module ActiveStorage::Blob::Representable
|
|
113
113
|
if filename.extension.present? && MiniMime.lookup_by_extension(filename.extension)&.content_type == content_type
|
114
114
|
filename.extension
|
115
115
|
else
|
116
|
-
MiniMime.lookup_by_content_type(content_type)
|
116
|
+
MiniMime.lookup_by_content_type(content_type)&.extension
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
@@ -49,7 +49,7 @@ class ActiveStorage::Blob < ActiveStorage::Record
|
|
49
49
|
scope :unattached, -> { where.missing(:attachments) }
|
50
50
|
|
51
51
|
after_initialize do
|
52
|
-
self.service_name ||= self.class.service
|
52
|
+
self.service_name ||= self.class.service&.name
|
53
53
|
end
|
54
54
|
|
55
55
|
after_update_commit :update_service_metadata, if: :content_type_previously_changed?
|
@@ -89,7 +89,7 @@ class ActiveStorage::Variant
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def filename
|
92
|
-
ActiveStorage::Filename.new "#{blob.filename.base}.#{variation.format}"
|
92
|
+
ActiveStorage::Filename.new "#{blob.filename.base}.#{variation.format.downcase}"
|
93
93
|
end
|
94
94
|
|
95
95
|
alias_method :content_type_for_serving, :content_type
|
@@ -33,7 +33,7 @@ class ActiveStorage::VariantWithRecord
|
|
33
33
|
def transform_blob
|
34
34
|
blob.open do |input|
|
35
35
|
variation.transform(input) do |output|
|
36
|
-
yield io: output, filename: "#{blob.filename.base}.#{variation.format}",
|
36
|
+
yield io: output, filename: "#{blob.filename.base}.#{variation.format.downcase}",
|
37
37
|
content_type: variation.content_type, service_name: blob.service.name
|
38
38
|
end
|
39
39
|
end
|
@@ -73,6 +73,20 @@ module ActiveStorage
|
|
73
73
|
application/pdf
|
74
74
|
)
|
75
75
|
|
76
|
+
default_unsupported_image_processing_arguments = %w(
|
77
|
+
-debug
|
78
|
+
-display
|
79
|
+
-distribute-cache
|
80
|
+
-help
|
81
|
+
-path
|
82
|
+
-print
|
83
|
+
-set
|
84
|
+
-verbose
|
85
|
+
-version
|
86
|
+
-write
|
87
|
+
-write-mask
|
88
|
+
)
|
89
|
+
|
76
90
|
config.eager_load_namespaces << ActiveStorage
|
77
91
|
|
78
92
|
initializer "active_storage.configs" do
|
@@ -86,12 +100,16 @@ module ActiveStorage
|
|
86
100
|
ActiveStorage.draw_routes = app.config.active_storage.draw_routes != false
|
87
101
|
ActiveStorage.resolve_model_to_route = app.config.active_storage.resolve_model_to_route || :rails_storage_redirect
|
88
102
|
|
103
|
+
ActiveStorage.supported_image_processing_methods = app.config.active_storage.supported_image_processing_methods || []
|
104
|
+
ActiveStorage.unsupported_image_processing_arguments = app.config.active_storage.unsupported_image_processing_arguments || default_unsupported_image_processing_arguments
|
105
|
+
|
89
106
|
ActiveStorage.variable_content_types = app.config.active_storage.variable_content_types || []
|
90
107
|
ActiveStorage.web_image_content_types = app.config.active_storage.web_image_content_types || []
|
91
108
|
ActiveStorage.content_types_to_serve_as_binary = app.config.active_storage.content_types_to_serve_as_binary || []
|
92
109
|
ActiveStorage.service_urls_expire_in = app.config.active_storage.service_urls_expire_in || 5.minutes
|
93
110
|
ActiveStorage.content_types_allowed_inline = app.config.active_storage.content_types_allowed_inline || []
|
94
111
|
ActiveStorage.binary_content_type = app.config.active_storage.binary_content_type || "application/octet-stream"
|
112
|
+
ActiveStorage.video_preview_arguments = app.config.active_storage.video_preview_arguments || "-y -vframes 1 -f image2"
|
95
113
|
|
96
114
|
ActiveStorage.replace_on_assign_to_many = app.config.active_storage.replace_on_assign_to_many || false
|
97
115
|
ActiveStorage.track_variants = app.config.active_storage.track_variants || false
|
@@ -23,4 +23,7 @@ module ActiveStorage
|
|
23
23
|
# Raised when ActiveStorage::Blob#download is called on a blob where the
|
24
24
|
# backing file is no longer present in its service.
|
25
25
|
class FileNotFoundError < Error; end
|
26
|
+
|
27
|
+
# Raised when a Previewer is unable to generate a preview image.
|
28
|
+
class PreviewError < Error; end
|
26
29
|
end
|
@@ -28,7 +28,7 @@ module ActiveStorage
|
|
28
28
|
|
29
29
|
private
|
30
30
|
def draw_relevant_frame_from(file, &block)
|
31
|
-
draw self.class.ffmpeg_path, "-i", file.path,
|
31
|
+
draw self.class.ffmpeg_path, "-i", file.path, *Shellwords.split(ActiveStorage.video_preview_arguments), "-", &block
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
@@ -70,7 +70,16 @@ module ActiveStorage
|
|
70
70
|
|
71
71
|
def capture(*argv, to:)
|
72
72
|
to.binmode
|
73
|
-
|
73
|
+
|
74
|
+
open_tempfile do |err|
|
75
|
+
IO.popen(argv, err: err) { |out| IO.copy_stream(out, to) }
|
76
|
+
err.rewind
|
77
|
+
|
78
|
+
unless $?.success?
|
79
|
+
raise PreviewError, "#{argv.first} failed (status #{$?.exitstatus}): #{err.read.to_s.chomp}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
74
83
|
to.rewind
|
75
84
|
end
|
76
85
|
|
@@ -13,6 +13,300 @@ module ActiveStorage
|
|
13
13
|
module Transformers
|
14
14
|
class ImageProcessingTransformer < Transformer
|
15
15
|
private
|
16
|
+
class UnsupportedImageProcessingMethod < StandardError; end
|
17
|
+
class UnsupportedImageProcessingArgument < StandardError; end
|
18
|
+
SUPPORTED_IMAGE_PROCESSING_METHODS = [
|
19
|
+
"adaptive_blur",
|
20
|
+
"adaptive_resize",
|
21
|
+
"adaptive_sharpen",
|
22
|
+
"adjoin",
|
23
|
+
"affine",
|
24
|
+
"alpha",
|
25
|
+
"annotate",
|
26
|
+
"antialias",
|
27
|
+
"append",
|
28
|
+
"apply",
|
29
|
+
"attenuate",
|
30
|
+
"authenticate",
|
31
|
+
"auto_gamma",
|
32
|
+
"auto_level",
|
33
|
+
"auto_orient",
|
34
|
+
"auto_threshold",
|
35
|
+
"backdrop",
|
36
|
+
"background",
|
37
|
+
"bench",
|
38
|
+
"bias",
|
39
|
+
"bilateral_blur",
|
40
|
+
"black_point_compensation",
|
41
|
+
"black_threshold",
|
42
|
+
"blend",
|
43
|
+
"blue_primary",
|
44
|
+
"blue_shift",
|
45
|
+
"blur",
|
46
|
+
"border",
|
47
|
+
"bordercolor",
|
48
|
+
"borderwidth",
|
49
|
+
"brightness_contrast",
|
50
|
+
"cache",
|
51
|
+
"canny",
|
52
|
+
"caption",
|
53
|
+
"channel",
|
54
|
+
"channel_fx",
|
55
|
+
"charcoal",
|
56
|
+
"chop",
|
57
|
+
"clahe",
|
58
|
+
"clamp",
|
59
|
+
"clip",
|
60
|
+
"clip_path",
|
61
|
+
"clone",
|
62
|
+
"clut",
|
63
|
+
"coalesce",
|
64
|
+
"colorize",
|
65
|
+
"colormap",
|
66
|
+
"color_matrix",
|
67
|
+
"colors",
|
68
|
+
"colorspace",
|
69
|
+
"colourspace",
|
70
|
+
"color_threshold",
|
71
|
+
"combine",
|
72
|
+
"combine_options",
|
73
|
+
"comment",
|
74
|
+
"compare",
|
75
|
+
"complex",
|
76
|
+
"compose",
|
77
|
+
"composite",
|
78
|
+
"compress",
|
79
|
+
"connected_components",
|
80
|
+
"contrast",
|
81
|
+
"contrast_stretch",
|
82
|
+
"convert",
|
83
|
+
"convolve",
|
84
|
+
"copy",
|
85
|
+
"crop",
|
86
|
+
"cycle",
|
87
|
+
"deconstruct",
|
88
|
+
"define",
|
89
|
+
"delay",
|
90
|
+
"delete",
|
91
|
+
"density",
|
92
|
+
"depth",
|
93
|
+
"descend",
|
94
|
+
"deskew",
|
95
|
+
"despeckle",
|
96
|
+
"direction",
|
97
|
+
"displace",
|
98
|
+
"dispose",
|
99
|
+
"dissimilarity_threshold",
|
100
|
+
"dissolve",
|
101
|
+
"distort",
|
102
|
+
"dither",
|
103
|
+
"draw",
|
104
|
+
"duplicate",
|
105
|
+
"edge",
|
106
|
+
"emboss",
|
107
|
+
"encoding",
|
108
|
+
"endian",
|
109
|
+
"enhance",
|
110
|
+
"equalize",
|
111
|
+
"evaluate",
|
112
|
+
"evaluate_sequence",
|
113
|
+
"extent",
|
114
|
+
"extract",
|
115
|
+
"family",
|
116
|
+
"features",
|
117
|
+
"fft",
|
118
|
+
"fill",
|
119
|
+
"filter",
|
120
|
+
"flatten",
|
121
|
+
"flip",
|
122
|
+
"floodfill",
|
123
|
+
"flop",
|
124
|
+
"font",
|
125
|
+
"foreground",
|
126
|
+
"format",
|
127
|
+
"frame",
|
128
|
+
"function",
|
129
|
+
"fuzz",
|
130
|
+
"fx",
|
131
|
+
"gamma",
|
132
|
+
"gaussian_blur",
|
133
|
+
"geometry",
|
134
|
+
"gravity",
|
135
|
+
"grayscale",
|
136
|
+
"green_primary",
|
137
|
+
"hald_clut",
|
138
|
+
"highlight_color",
|
139
|
+
"hough_lines",
|
140
|
+
"iconGeometry",
|
141
|
+
"iconic",
|
142
|
+
"identify",
|
143
|
+
"ift",
|
144
|
+
"illuminant",
|
145
|
+
"immutable",
|
146
|
+
"implode",
|
147
|
+
"insert",
|
148
|
+
"intensity",
|
149
|
+
"intent",
|
150
|
+
"interlace",
|
151
|
+
"interline_spacing",
|
152
|
+
"interpolate",
|
153
|
+
"interpolative_resize",
|
154
|
+
"interword_spacing",
|
155
|
+
"kerning",
|
156
|
+
"kmeans",
|
157
|
+
"kuwahara",
|
158
|
+
"label",
|
159
|
+
"lat",
|
160
|
+
"layers",
|
161
|
+
"level",
|
162
|
+
"level_colors",
|
163
|
+
"limit",
|
164
|
+
"limits",
|
165
|
+
"linear_stretch",
|
166
|
+
"linewidth",
|
167
|
+
"liquid_rescale",
|
168
|
+
"list",
|
169
|
+
"loader",
|
170
|
+
"log",
|
171
|
+
"loop",
|
172
|
+
"lowlight_color",
|
173
|
+
"magnify",
|
174
|
+
"map",
|
175
|
+
"mattecolor",
|
176
|
+
"median",
|
177
|
+
"mean_shift",
|
178
|
+
"metric",
|
179
|
+
"mode",
|
180
|
+
"modulate",
|
181
|
+
"moments",
|
182
|
+
"monitor",
|
183
|
+
"monochrome",
|
184
|
+
"morph",
|
185
|
+
"morphology",
|
186
|
+
"mosaic",
|
187
|
+
"motion_blur",
|
188
|
+
"name",
|
189
|
+
"negate",
|
190
|
+
"noise",
|
191
|
+
"normalize",
|
192
|
+
"opaque",
|
193
|
+
"ordered_dither",
|
194
|
+
"orient",
|
195
|
+
"page",
|
196
|
+
"paint",
|
197
|
+
"pause",
|
198
|
+
"perceptible",
|
199
|
+
"ping",
|
200
|
+
"pointsize",
|
201
|
+
"polaroid",
|
202
|
+
"poly",
|
203
|
+
"posterize",
|
204
|
+
"precision",
|
205
|
+
"preview",
|
206
|
+
"process",
|
207
|
+
"quality",
|
208
|
+
"quantize",
|
209
|
+
"quiet",
|
210
|
+
"radial_blur",
|
211
|
+
"raise",
|
212
|
+
"random_threshold",
|
213
|
+
"range_threshold",
|
214
|
+
"red_primary",
|
215
|
+
"regard_warnings",
|
216
|
+
"region",
|
217
|
+
"remote",
|
218
|
+
"render",
|
219
|
+
"repage",
|
220
|
+
"resample",
|
221
|
+
"resize",
|
222
|
+
"resize_to_fill",
|
223
|
+
"resize_to_fit",
|
224
|
+
"resize_to_limit",
|
225
|
+
"resize_and_pad",
|
226
|
+
"respect_parentheses",
|
227
|
+
"reverse",
|
228
|
+
"roll",
|
229
|
+
"rotate",
|
230
|
+
"sample",
|
231
|
+
"sampling_factor",
|
232
|
+
"saver",
|
233
|
+
"scale",
|
234
|
+
"scene",
|
235
|
+
"screen",
|
236
|
+
"seed",
|
237
|
+
"segment",
|
238
|
+
"selective_blur",
|
239
|
+
"separate",
|
240
|
+
"sepia_tone",
|
241
|
+
"shade",
|
242
|
+
"shadow",
|
243
|
+
"shared_memory",
|
244
|
+
"sharpen",
|
245
|
+
"shave",
|
246
|
+
"shear",
|
247
|
+
"sigmoidal_contrast",
|
248
|
+
"silent",
|
249
|
+
"similarity_threshold",
|
250
|
+
"size",
|
251
|
+
"sketch",
|
252
|
+
"smush",
|
253
|
+
"snaps",
|
254
|
+
"solarize",
|
255
|
+
"sort_pixels",
|
256
|
+
"sparse_color",
|
257
|
+
"splice",
|
258
|
+
"spread",
|
259
|
+
"statistic",
|
260
|
+
"stegano",
|
261
|
+
"stereo",
|
262
|
+
"storage_type",
|
263
|
+
"stretch",
|
264
|
+
"strip",
|
265
|
+
"stroke",
|
266
|
+
"strokewidth",
|
267
|
+
"style",
|
268
|
+
"subimage_search",
|
269
|
+
"swap",
|
270
|
+
"swirl",
|
271
|
+
"synchronize",
|
272
|
+
"taint",
|
273
|
+
"text_font",
|
274
|
+
"threshold",
|
275
|
+
"thumbnail",
|
276
|
+
"tile_offset",
|
277
|
+
"tint",
|
278
|
+
"title",
|
279
|
+
"transform",
|
280
|
+
"transparent",
|
281
|
+
"transparent_color",
|
282
|
+
"transpose",
|
283
|
+
"transverse",
|
284
|
+
"treedepth",
|
285
|
+
"trim",
|
286
|
+
"type",
|
287
|
+
"undercolor",
|
288
|
+
"unique_colors",
|
289
|
+
"units",
|
290
|
+
"unsharp",
|
291
|
+
"update",
|
292
|
+
"valid_image",
|
293
|
+
"view",
|
294
|
+
"vignette",
|
295
|
+
"virtual_pixel",
|
296
|
+
"visual",
|
297
|
+
"watermark",
|
298
|
+
"wave",
|
299
|
+
"wavelet_denoise",
|
300
|
+
"weight",
|
301
|
+
"white_balance",
|
302
|
+
"white_point",
|
303
|
+
"white_threshold",
|
304
|
+
"window",
|
305
|
+
"window_group"
|
306
|
+
].concat(ActiveStorage.supported_image_processing_methods)
|
307
|
+
|
308
|
+
UNSUPPORTED_IMAGE_PROCESSING_ARGUMENTS = ActiveStorage.unsupported_image_processing_arguments
|
309
|
+
|
16
310
|
def process(file, format:)
|
17
311
|
processor.
|
18
312
|
source(file).
|
@@ -28,6 +322,10 @@ module ActiveStorage
|
|
28
322
|
|
29
323
|
def operations
|
30
324
|
transformations.each_with_object([]) do |(name, argument), list|
|
325
|
+
if ActiveStorage.variant_processor == :mini_magick
|
326
|
+
validate_transformation(name, argument)
|
327
|
+
end
|
328
|
+
|
31
329
|
if name.to_s == "combine_options"
|
32
330
|
raise ArgumentError, <<~ERROR.squish
|
33
331
|
Active Storage's ImageProcessing transformer doesn't support :combine_options,
|
@@ -40,6 +338,60 @@ module ActiveStorage
|
|
40
338
|
end
|
41
339
|
end
|
42
340
|
end
|
341
|
+
|
342
|
+
def validate_transformation(name, argument)
|
343
|
+
method_name = name.to_s.gsub("-","_")
|
344
|
+
|
345
|
+
unless SUPPORTED_IMAGE_PROCESSING_METHODS.any? { |method| method_name == method }
|
346
|
+
raise UnsupportedImageProcessingMethod, <<~ERROR.squish
|
347
|
+
One or more of the provided transformation methods is not supported.
|
348
|
+
ERROR
|
349
|
+
end
|
350
|
+
|
351
|
+
if argument.present?
|
352
|
+
if argument.is_a?(String) || argument.is_a?(Symbol)
|
353
|
+
validate_arg_string(argument)
|
354
|
+
elsif argument.is_a?(Array)
|
355
|
+
validate_arg_array(argument)
|
356
|
+
elsif argument.is_a?(Hash)
|
357
|
+
validate_arg_hash(argument)
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
def validate_arg_string(argument)
|
363
|
+
if UNSUPPORTED_IMAGE_PROCESSING_ARGUMENTS.any? { |bad_arg| argument.to_s.downcase.include?(bad_arg) }; raise UnsupportedImageProcessingArgument end
|
364
|
+
end
|
365
|
+
|
366
|
+
def validate_arg_array(argument)
|
367
|
+
argument.each do |arg|
|
368
|
+
if arg.is_a?(Integer) || arg.is_a?(Float)
|
369
|
+
next
|
370
|
+
elsif arg.is_a?(String) || arg.is_a?(Symbol)
|
371
|
+
validate_arg_string(arg)
|
372
|
+
elsif arg.is_a?(Array)
|
373
|
+
validate_arg_array(arg)
|
374
|
+
elsif arg.is_a?(Hash)
|
375
|
+
validate_arg_hash(arg)
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
def validate_arg_hash(argument)
|
381
|
+
argument.each do |key, value|
|
382
|
+
validate_arg_string(key)
|
383
|
+
|
384
|
+
if value.is_a?(Integer) || value.is_a?(Float)
|
385
|
+
next
|
386
|
+
elsif value.is_a?(String) || value.is_a?(Symbol)
|
387
|
+
validate_arg_string(value)
|
388
|
+
elsif value.is_a?(Array)
|
389
|
+
validate_arg_array(value)
|
390
|
+
elsif value.is_a?(Hash)
|
391
|
+
validate_arg_hash(value)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
43
395
|
end
|
44
396
|
end
|
45
397
|
end
|
data/lib/active_storage.rb
CHANGED
@@ -58,6 +58,9 @@ module ActiveStorage
|
|
58
58
|
mattr_accessor :content_types_to_serve_as_binary, default: []
|
59
59
|
mattr_accessor :content_types_allowed_inline, default: []
|
60
60
|
|
61
|
+
mattr_accessor :supported_image_processing_methods, default: []
|
62
|
+
mattr_accessor :unsupported_image_processing_arguments
|
63
|
+
|
61
64
|
mattr_accessor :service_urls_expire_in, default: 5.minutes
|
62
65
|
|
63
66
|
mattr_accessor :routes_prefix, default: "/rails/active_storage"
|
@@ -67,6 +70,8 @@ module ActiveStorage
|
|
67
70
|
mattr_accessor :replace_on_assign_to_many, default: false
|
68
71
|
mattr_accessor :track_variants, default: false
|
69
72
|
|
73
|
+
mattr_accessor :video_preview_arguments, default: "-y -vframes 1 -f image2"
|
74
|
+
|
70
75
|
module Transformers
|
71
76
|
extend ActiveSupport::Autoload
|
72
77
|
|
@@ -17,6 +17,10 @@ namespace :active_storage do
|
|
17
17
|
task update: :environment do
|
18
18
|
ENV["MIGRATIONS_PATH"] = "db/update_migrate"
|
19
19
|
|
20
|
-
Rake::Task
|
20
|
+
if Rake::Task.task_defined?("active_storage:install")
|
21
|
+
Rake::Task["active_storage:install"].invoke
|
22
|
+
else
|
23
|
+
Rake::Task["app:active_storage:install"].invoke
|
24
|
+
end
|
21
25
|
end
|
22
26
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activestorage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.1.
|
4
|
+
version: 6.1.4.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,56 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 6.1.
|
19
|
+
version: 6.1.4.7
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 6.1.
|
26
|
+
version: 6.1.4.7
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: actionpack
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 6.1.
|
33
|
+
version: 6.1.4.7
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 6.1.
|
40
|
+
version: 6.1.4.7
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: activejob
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 6.1.
|
47
|
+
version: 6.1.4.7
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 6.1.
|
54
|
+
version: 6.1.4.7
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: activerecord
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 6.1.
|
61
|
+
version: 6.1.4.7
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 6.1.
|
68
|
+
version: 6.1.4.7
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: marcel
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,16 +84,16 @@ dependencies:
|
|
84
84
|
name: mini_mime
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 1.0
|
89
|
+
version: 1.1.0
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 1.0
|
96
|
+
version: 1.1.0
|
97
97
|
description: Attach cloud and local files in Rails applications.
|
98
98
|
email: david@loudthinking.com
|
99
99
|
executables: []
|
@@ -109,6 +109,7 @@ files:
|
|
109
109
|
- app/controllers/active_storage/blobs/redirect_controller.rb
|
110
110
|
- app/controllers/active_storage/direct_uploads_controller.rb
|
111
111
|
- app/controllers/active_storage/disk_controller.rb
|
112
|
+
- app/controllers/active_storage/representations/base_controller.rb
|
112
113
|
- app/controllers/active_storage/representations/proxy_controller.rb
|
113
114
|
- app/controllers/active_storage/representations/redirect_controller.rb
|
114
115
|
- app/controllers/concerns/active_storage/file_server.rb
|
@@ -187,10 +188,10 @@ licenses:
|
|
187
188
|
- MIT
|
188
189
|
metadata:
|
189
190
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
190
|
-
changelog_uri: https://github.com/rails/rails/blob/v6.1.
|
191
|
-
documentation_uri: https://api.rubyonrails.org/v6.1.
|
191
|
+
changelog_uri: https://github.com/rails/rails/blob/v6.1.4.7/activestorage/CHANGELOG.md
|
192
|
+
documentation_uri: https://api.rubyonrails.org/v6.1.4.7/
|
192
193
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
193
|
-
source_code_uri: https://github.com/rails/rails/tree/v6.1.
|
194
|
+
source_code_uri: https://github.com/rails/rails/tree/v6.1.4.7/activestorage
|
194
195
|
post_install_message:
|
195
196
|
rdoc_options: []
|
196
197
|
require_paths:
|
@@ -206,7 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
207
|
- !ruby/object:Gem::Version
|
207
208
|
version: '0'
|
208
209
|
requirements: []
|
209
|
-
rubygems_version: 3.1.
|
210
|
+
rubygems_version: 3.1.6
|
210
211
|
signing_key:
|
211
212
|
specification_version: 4
|
212
213
|
summary: Local and cloud file storage framework.
|