activestorage 6.1.1 → 6.1.6
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 +112 -0
- data/MIT-LICENSE +1 -1
- data/README.md +1 -1
- 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/attachment.rb +1 -1
- data/app/models/active_storage/blob/representable.rb +3 -3
- data/app/models/active_storage/blob.rb +11 -3
- data/app/models/active_storage/variant.rb +4 -4
- data/app/models/active_storage/variant_with_record.rb +1 -1
- data/app/models/active_storage/variation.rb +4 -4
- data/lib/active_storage/engine.rb +16 -0
- data/lib/active_storage/errors.rb +3 -0
- data/lib/active_storage/gem_version.rb +1 -1
- data/lib/active_storage/previewer/video_previewer.rb +3 -1
- data/lib/active_storage/previewer.rb +10 -1
- data/lib/active_storage/transformers/image_processing_transformer.rb +65 -0
- data/lib/active_storage.rb +294 -1
- data/lib/tasks/activestorage.rake +5 -1
- metadata +23 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 985aeed1b2150be57a83d7779240e61be0b36689b342ccd710c8ba35c3f6c84d
|
4
|
+
data.tar.gz: 8334b4728bd51120473b7f720a20cda36df0f6f96acaf2e76c12d0eb94bf95a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5227ab769b5adff20f44dc3bca81e3eca7e72fe589d0dbec32be507a57bb6f285d55289934340214ee692d8a38ff421e59658c9b60c6da5ddee96336eed688ab
|
7
|
+
data.tar.gz: c3490ed2c45b821f619d6837f9adffbc43c854d953bf43e29c0092452819c53a95ed87b5f45c3fed6e0f169070b6532f4bbb85cbc5bf64e8d1fc4cf90df2ca63
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,115 @@
|
|
1
|
+
## Rails 6.1.5.1 (April 26, 2022) ##
|
2
|
+
|
3
|
+
* No changes.
|
4
|
+
|
5
|
+
|
6
|
+
## Rails 6.1.5 (March 09, 2022) ##
|
7
|
+
|
8
|
+
* Attachments can be deleted after their association is no longer defined.
|
9
|
+
|
10
|
+
Fixes #42514
|
11
|
+
|
12
|
+
*Don Sisco*
|
13
|
+
|
14
|
+
|
15
|
+
## Rails 6.1.4.7 (March 08, 2022) ##
|
16
|
+
|
17
|
+
* Added image transformation validation via configurable allow-list.
|
18
|
+
|
19
|
+
Variant now offers a configurable allow-list for
|
20
|
+
transformation methods in addition to a configurable deny-list for arguments.
|
21
|
+
|
22
|
+
[CVE-2022-21831]
|
23
|
+
|
24
|
+
|
25
|
+
## Rails 6.1.4.6 (February 11, 2022) ##
|
26
|
+
|
27
|
+
* No changes.
|
28
|
+
|
29
|
+
|
30
|
+
## Rails 6.1.4.5 (February 11, 2022) ##
|
31
|
+
|
32
|
+
* No changes.
|
33
|
+
|
34
|
+
|
35
|
+
## Rails 6.1.4.4 (December 15, 2021) ##
|
36
|
+
|
37
|
+
* No changes.
|
38
|
+
|
39
|
+
|
40
|
+
## Rails 6.1.4.3 (December 14, 2021) ##
|
41
|
+
|
42
|
+
* No changes.
|
43
|
+
|
44
|
+
|
45
|
+
## Rails 6.1.4.2 (December 14, 2021) ##
|
46
|
+
|
47
|
+
* No changes.
|
48
|
+
|
49
|
+
|
50
|
+
## Rails 6.1.4.1 (August 19, 2021) ##
|
51
|
+
|
52
|
+
* No changes.
|
53
|
+
|
54
|
+
|
55
|
+
## Rails 6.1.4 (June 24, 2021) ##
|
56
|
+
|
57
|
+
* The parameters sent to `ffmpeg` for generating a video preview image are now
|
58
|
+
configurable under `config.active_storage.video_preview_arguments`.
|
59
|
+
|
60
|
+
*Brendon Muir*
|
61
|
+
|
62
|
+
* Fix Active Storage update task when running in an engine.
|
63
|
+
|
64
|
+
*Justin Malčić*
|
65
|
+
|
66
|
+
* Don't raise an error if the mime type is not recognized.
|
67
|
+
|
68
|
+
Fixes #41777.
|
69
|
+
|
70
|
+
*Alex Ghiculescu*
|
71
|
+
|
72
|
+
* `ActiveStorage::PreviewError` is raised when a previewer is unable to generate a preview image.
|
73
|
+
|
74
|
+
*Alex Robbin*
|
75
|
+
|
76
|
+
* respond with 404 given invalid variation key when asking for representations.
|
77
|
+
|
78
|
+
*George Claghorn*
|
79
|
+
|
80
|
+
* `Blob` creation shouldn't crash if no service selected.
|
81
|
+
|
82
|
+
*Alex Ghiculescu*
|
83
|
+
|
84
|
+
|
85
|
+
## Rails 6.1.3.2 (May 05, 2021) ##
|
86
|
+
|
87
|
+
* No changes.
|
88
|
+
|
89
|
+
|
90
|
+
## Rails 6.1.3.1 (March 26, 2021) ##
|
91
|
+
|
92
|
+
* Marcel is upgraded to version 1.0.0 to avoid a dependency on GPL-licensed
|
93
|
+
mime types data.
|
94
|
+
|
95
|
+
*George Claghorn*
|
96
|
+
|
97
|
+
|
98
|
+
## Rails 6.1.3 (February 17, 2021) ##
|
99
|
+
|
100
|
+
* No changes.
|
101
|
+
|
102
|
+
|
103
|
+
## Rails 6.1.2.1 (February 10, 2021) ##
|
104
|
+
|
105
|
+
* No changes.
|
106
|
+
|
107
|
+
|
108
|
+
## Rails 6.1.2 (February 09, 2021) ##
|
109
|
+
|
110
|
+
* No changes.
|
111
|
+
|
112
|
+
|
1
113
|
## Rails 6.1.1 (January 07, 2021) ##
|
2
114
|
|
3
115
|
* Fix S3 multipart uploads when threshold is larger than file.
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -10,7 +10,7 @@ You can read more about Active Storage in the [Active Storage Overview](https://
|
|
10
10
|
|
11
11
|
## Compared to other storage solutions
|
12
12
|
|
13
|
-
A key difference to how Active Storage works compared to other attachment solutions in Rails is through the use of built-in [Blob](https://github.com/rails/rails/blob/
|
13
|
+
A key difference to how Active Storage works compared to other attachment solutions in Rails is through the use of built-in [Blob](https://github.com/rails/rails/blob/main/activestorage/app/models/active_storage/blob.rb) and [Attachment](https://github.com/rails/rails/blob/main/activestorage/app/models/active_storage/attachment.rb) models (backed by Active Record). This means existing application models do not need to be modified with additional columns to associate with files. Active Storage uses polymorphic associations via the `Attachment` join model, which then connects to the actual `Blob`.
|
14
14
|
|
15
15
|
`Blob` models store attachment metadata (filename, content-type, etc.), and their identifier key in the storage service. Blob models do not store the actual binary data. They are intended to be immutable in spirit. One file, one blob. You can associate the same blob with multiple application models as well. And if you want to do transformations of a given `Blob`, the idea is that you'll simply create a new one, rather than attempt to mutate the existing one (though of course you can delete the previous version later if you don't need it).
|
16
16
|
|
@@ -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
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "mini_mime"
|
4
4
|
|
5
5
|
module ActiveStorage::Blob::Representable
|
6
6
|
extend ActiveSupport::Concern
|
@@ -110,10 +110,10 @@ module ActiveStorage::Blob::Representable
|
|
110
110
|
end
|
111
111
|
|
112
112
|
def format
|
113
|
-
if filename.extension.present? &&
|
113
|
+
if filename.extension.present? && MiniMime.lookup_by_extension(filename.extension)&.content_type == content_type
|
114
114
|
filename.extension
|
115
115
|
else
|
116
|
-
|
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?
|
@@ -74,8 +74,16 @@ class ActiveStorage::Blob < ActiveStorage::Record
|
|
74
74
|
# that was created ahead of the upload itself on form submission.
|
75
75
|
#
|
76
76
|
# The signed ID is also used to create stable URLs for the blob through the BlobsController.
|
77
|
-
def find_signed
|
78
|
-
super(id, purpose:
|
77
|
+
def find_signed(id, record: nil, purpose: :blob_id)
|
78
|
+
super(id, purpose: purpose)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Works like +find_signed+, but will raise an +ActiveSupport::MessageVerifier::InvalidSignature+
|
82
|
+
# exception if the +signed_id+ has either expired, has a purpose mismatch, is for another record,
|
83
|
+
# or has been tampered with. It will also raise an +ActiveRecord::RecordNotFound+ exception if
|
84
|
+
# the valid signed id can't find a record.
|
85
|
+
def find_signed!(id, record: nil, purpose: :blob_id)
|
86
|
+
super(id, purpose: purpose)
|
79
87
|
end
|
80
88
|
|
81
89
|
def build_after_upload(io:, filename:, content_type: nil, metadata: nil, service_name: nil, identify: true, record: nil) #:nodoc:
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# These variants are used to create thumbnails, fixed-size avatars, or any other derivative image from the
|
5
5
|
# original.
|
6
6
|
#
|
7
|
-
# Variants rely on {ImageProcessing}[https://github.com/janko
|
7
|
+
# Variants rely on {ImageProcessing}[https://github.com/janko/image_processing] gem for the actual transformations
|
8
8
|
# of the file, so you must add <tt>gem "image_processing"</tt> to your Gemfile if you wish to use variants. By
|
9
9
|
# default, images will be processed with {ImageMagick}[http://imagemagick.org] using the
|
10
10
|
# {MiniMagick}[https://github.com/minimagick/minimagick] gem, but you can also switch to the
|
@@ -46,9 +46,9 @@
|
|
46
46
|
#
|
47
47
|
# Visit the following links for a list of available ImageProcessing commands and ImageMagick/libvips operations:
|
48
48
|
#
|
49
|
-
# * {ImageProcessing::MiniMagick}[https://github.com/janko
|
49
|
+
# * {ImageProcessing::MiniMagick}[https://github.com/janko/image_processing/blob/master/doc/minimagick.md#methods]
|
50
50
|
# * {ImageMagick reference}[https://www.imagemagick.org/script/mogrify.php]
|
51
|
-
# * {ImageProcessing::Vips}[https://github.com/janko
|
51
|
+
# * {ImageProcessing::Vips}[https://github.com/janko/image_processing/blob/master/doc/vips.md#methods]
|
52
52
|
# * {ruby-vips reference}[http://www.rubydoc.info/gems/ruby-vips/Vips/Image]
|
53
53
|
class ActiveStorage::Variant
|
54
54
|
attr_reader :blob, :variation
|
@@ -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
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "mini_mime"
|
4
4
|
|
5
5
|
# A set of transformations that can be applied to a blob to create a variant. This class is exposed via
|
6
6
|
# the ActiveStorage::Blob#variant method and should rarely be used directly.
|
@@ -10,7 +10,7 @@ require "mimemagic"
|
|
10
10
|
#
|
11
11
|
# ActiveStorage::Variation.new(resize_to_limit: [100, 100], monochrome: true, trim: true, rotate: "-90")
|
12
12
|
#
|
13
|
-
# The options map directly to {ImageProcessing}[https://github.com/janko
|
13
|
+
# The options map directly to {ImageProcessing}[https://github.com/janko/image_processing] commands.
|
14
14
|
class ActiveStorage::Variation
|
15
15
|
attr_reader :transformations
|
16
16
|
|
@@ -59,14 +59,14 @@ class ActiveStorage::Variation
|
|
59
59
|
|
60
60
|
def format
|
61
61
|
transformations.fetch(:format, :png).tap do |format|
|
62
|
-
if
|
62
|
+
if MiniMime.lookup_by_extension(format.to_s).nil?
|
63
63
|
raise ArgumentError, "Invalid variant format (#{format.inspect})"
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
68
|
def content_type
|
69
|
-
|
69
|
+
MiniMime.lookup_by_extension(format.to_s).content_type
|
70
70
|
end
|
71
71
|
|
72
72
|
# Returns a signed key for all the +transformations+ that this variation was instantiated with.
|
@@ -86,12 +86,28 @@ module ActiveStorage
|
|
86
86
|
ActiveStorage.draw_routes = app.config.active_storage.draw_routes != false
|
87
87
|
ActiveStorage.resolve_model_to_route = app.config.active_storage.resolve_model_to_route || :rails_storage_redirect
|
88
88
|
|
89
|
+
ActiveStorage.supported_image_processing_methods += app.config.active_storage.supported_image_processing_methods || []
|
90
|
+
ActiveStorage.unsupported_image_processing_arguments = app.config.active_storage.unsupported_image_processing_arguments || %w(
|
91
|
+
-debug
|
92
|
+
-display
|
93
|
+
-distribute-cache
|
94
|
+
-help
|
95
|
+
-path
|
96
|
+
-print
|
97
|
+
-set
|
98
|
+
-verbose
|
99
|
+
-version
|
100
|
+
-write
|
101
|
+
-write-mask
|
102
|
+
)
|
103
|
+
|
89
104
|
ActiveStorage.variable_content_types = app.config.active_storage.variable_content_types || []
|
90
105
|
ActiveStorage.web_image_content_types = app.config.active_storage.web_image_content_types || []
|
91
106
|
ActiveStorage.content_types_to_serve_as_binary = app.config.active_storage.content_types_to_serve_as_binary || []
|
92
107
|
ActiveStorage.service_urls_expire_in = app.config.active_storage.service_urls_expire_in || 5.minutes
|
93
108
|
ActiveStorage.content_types_allowed_inline = app.config.active_storage.content_types_allowed_inline || []
|
94
109
|
ActiveStorage.binary_content_type = app.config.active_storage.binary_content_type || "application/octet-stream"
|
110
|
+
ActiveStorage.video_preview_arguments = app.config.active_storage.video_preview_arguments || "-y -vframes 1 -f image2"
|
95
111
|
|
96
112
|
ActiveStorage.replace_on_assign_to_many = app.config.active_storage.replace_on_assign_to_many || false
|
97
113
|
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
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "shellwords"
|
4
|
+
|
3
5
|
module ActiveStorage
|
4
6
|
class Previewer::VideoPreviewer < Previewer
|
5
7
|
class << self
|
@@ -28,7 +30,7 @@ module ActiveStorage
|
|
28
30
|
|
29
31
|
private
|
30
32
|
def draw_relevant_frame_from(file, &block)
|
31
|
-
draw self.class.ffmpeg_path, "-i", file.path,
|
33
|
+
draw self.class.ffmpeg_path, "-i", file.path, *Shellwords.split(ActiveStorage.video_preview_arguments), "-", &block
|
32
34
|
end
|
33
35
|
end
|
34
36
|
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,9 @@ 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
|
+
|
16
19
|
def process(file, format:)
|
17
20
|
processor.
|
18
21
|
source(file).
|
@@ -28,6 +31,10 @@ module ActiveStorage
|
|
28
31
|
|
29
32
|
def operations
|
30
33
|
transformations.each_with_object([]) do |(name, argument), list|
|
34
|
+
if ActiveStorage.variant_processor == :mini_magick
|
35
|
+
validate_transformation(name, argument)
|
36
|
+
end
|
37
|
+
|
31
38
|
if name.to_s == "combine_options"
|
32
39
|
raise ArgumentError, <<~ERROR.squish
|
33
40
|
Active Storage's ImageProcessing transformer doesn't support :combine_options,
|
@@ -40,6 +47,64 @@ module ActiveStorage
|
|
40
47
|
end
|
41
48
|
end
|
42
49
|
end
|
50
|
+
|
51
|
+
def validate_transformation(name, argument)
|
52
|
+
method_name = name.to_s.tr("-", "_")
|
53
|
+
|
54
|
+
unless ActiveStorage.supported_image_processing_methods.any? { |method| method_name == method }
|
55
|
+
raise UnsupportedImageProcessingMethod, <<~ERROR.squish
|
56
|
+
One or more of the provided transformation methods is not supported.
|
57
|
+
ERROR
|
58
|
+
end
|
59
|
+
|
60
|
+
if argument.present?
|
61
|
+
if argument.is_a?(String) || argument.is_a?(Symbol)
|
62
|
+
validate_arg_string(argument)
|
63
|
+
elsif argument.is_a?(Array)
|
64
|
+
validate_arg_array(argument)
|
65
|
+
elsif argument.is_a?(Hash)
|
66
|
+
validate_arg_hash(argument)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def validate_arg_string(argument)
|
72
|
+
unsupported_arguments = ActiveStorage.unsupported_image_processing_arguments.any? do |bad_arg|
|
73
|
+
argument.to_s.downcase.include?(bad_arg)
|
74
|
+
end
|
75
|
+
|
76
|
+
raise UnsupportedImageProcessingArgument if unsupported_arguments
|
77
|
+
end
|
78
|
+
|
79
|
+
def validate_arg_array(argument)
|
80
|
+
argument.each do |arg|
|
81
|
+
if arg.is_a?(Integer) || arg.is_a?(Float)
|
82
|
+
next
|
83
|
+
elsif arg.is_a?(String) || arg.is_a?(Symbol)
|
84
|
+
validate_arg_string(arg)
|
85
|
+
elsif arg.is_a?(Array)
|
86
|
+
validate_arg_array(arg)
|
87
|
+
elsif arg.is_a?(Hash)
|
88
|
+
validate_arg_hash(arg)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def validate_arg_hash(argument)
|
94
|
+
argument.each do |key, value|
|
95
|
+
validate_arg_string(key)
|
96
|
+
|
97
|
+
if value.is_a?(Integer) || value.is_a?(Float)
|
98
|
+
next
|
99
|
+
elsif value.is_a?(String) || value.is_a?(Symbol)
|
100
|
+
validate_arg_string(value)
|
101
|
+
elsif value.is_a?(Array)
|
102
|
+
validate_arg_array(value)
|
103
|
+
elsif value.is_a?(Hash)
|
104
|
+
validate_arg_hash(value)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
43
108
|
end
|
44
109
|
end
|
45
110
|
end
|
data/lib/active_storage.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2017-
|
4
|
+
# Copyright (c) 2017-2022 David Heinemeier Hansson, Basecamp
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
@@ -58,6 +58,297 @@ 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
|
+
"adaptive_blur",
|
63
|
+
"adaptive_resize",
|
64
|
+
"adaptive_sharpen",
|
65
|
+
"adjoin",
|
66
|
+
"affine",
|
67
|
+
"alpha",
|
68
|
+
"annotate",
|
69
|
+
"antialias",
|
70
|
+
"append",
|
71
|
+
"apply",
|
72
|
+
"attenuate",
|
73
|
+
"authenticate",
|
74
|
+
"auto_gamma",
|
75
|
+
"auto_level",
|
76
|
+
"auto_orient",
|
77
|
+
"auto_threshold",
|
78
|
+
"backdrop",
|
79
|
+
"background",
|
80
|
+
"bench",
|
81
|
+
"bias",
|
82
|
+
"bilateral_blur",
|
83
|
+
"black_point_compensation",
|
84
|
+
"black_threshold",
|
85
|
+
"blend",
|
86
|
+
"blue_primary",
|
87
|
+
"blue_shift",
|
88
|
+
"blur",
|
89
|
+
"border",
|
90
|
+
"bordercolor",
|
91
|
+
"borderwidth",
|
92
|
+
"brightness_contrast",
|
93
|
+
"cache",
|
94
|
+
"canny",
|
95
|
+
"caption",
|
96
|
+
"channel",
|
97
|
+
"channel_fx",
|
98
|
+
"charcoal",
|
99
|
+
"chop",
|
100
|
+
"clahe",
|
101
|
+
"clamp",
|
102
|
+
"clip",
|
103
|
+
"clip_path",
|
104
|
+
"clone",
|
105
|
+
"clut",
|
106
|
+
"coalesce",
|
107
|
+
"colorize",
|
108
|
+
"colormap",
|
109
|
+
"color_matrix",
|
110
|
+
"colors",
|
111
|
+
"colorspace",
|
112
|
+
"colourspace",
|
113
|
+
"color_threshold",
|
114
|
+
"combine",
|
115
|
+
"combine_options",
|
116
|
+
"comment",
|
117
|
+
"compare",
|
118
|
+
"complex",
|
119
|
+
"compose",
|
120
|
+
"composite",
|
121
|
+
"compress",
|
122
|
+
"connected_components",
|
123
|
+
"contrast",
|
124
|
+
"contrast_stretch",
|
125
|
+
"convert",
|
126
|
+
"convolve",
|
127
|
+
"copy",
|
128
|
+
"crop",
|
129
|
+
"cycle",
|
130
|
+
"deconstruct",
|
131
|
+
"define",
|
132
|
+
"delay",
|
133
|
+
"delete",
|
134
|
+
"density",
|
135
|
+
"depth",
|
136
|
+
"descend",
|
137
|
+
"deskew",
|
138
|
+
"despeckle",
|
139
|
+
"direction",
|
140
|
+
"displace",
|
141
|
+
"dispose",
|
142
|
+
"dissimilarity_threshold",
|
143
|
+
"dissolve",
|
144
|
+
"distort",
|
145
|
+
"dither",
|
146
|
+
"draw",
|
147
|
+
"duplicate",
|
148
|
+
"edge",
|
149
|
+
"emboss",
|
150
|
+
"encoding",
|
151
|
+
"endian",
|
152
|
+
"enhance",
|
153
|
+
"equalize",
|
154
|
+
"evaluate",
|
155
|
+
"evaluate_sequence",
|
156
|
+
"extent",
|
157
|
+
"extract",
|
158
|
+
"family",
|
159
|
+
"features",
|
160
|
+
"fft",
|
161
|
+
"fill",
|
162
|
+
"filter",
|
163
|
+
"flatten",
|
164
|
+
"flip",
|
165
|
+
"floodfill",
|
166
|
+
"flop",
|
167
|
+
"font",
|
168
|
+
"foreground",
|
169
|
+
"format",
|
170
|
+
"frame",
|
171
|
+
"function",
|
172
|
+
"fuzz",
|
173
|
+
"fx",
|
174
|
+
"gamma",
|
175
|
+
"gaussian_blur",
|
176
|
+
"geometry",
|
177
|
+
"gravity",
|
178
|
+
"grayscale",
|
179
|
+
"green_primary",
|
180
|
+
"hald_clut",
|
181
|
+
"highlight_color",
|
182
|
+
"hough_lines",
|
183
|
+
"iconGeometry",
|
184
|
+
"iconic",
|
185
|
+
"identify",
|
186
|
+
"ift",
|
187
|
+
"illuminant",
|
188
|
+
"immutable",
|
189
|
+
"implode",
|
190
|
+
"insert",
|
191
|
+
"intensity",
|
192
|
+
"intent",
|
193
|
+
"interlace",
|
194
|
+
"interline_spacing",
|
195
|
+
"interpolate",
|
196
|
+
"interpolative_resize",
|
197
|
+
"interword_spacing",
|
198
|
+
"kerning",
|
199
|
+
"kmeans",
|
200
|
+
"kuwahara",
|
201
|
+
"label",
|
202
|
+
"lat",
|
203
|
+
"layers",
|
204
|
+
"level",
|
205
|
+
"level_colors",
|
206
|
+
"limit",
|
207
|
+
"limits",
|
208
|
+
"linear_stretch",
|
209
|
+
"linewidth",
|
210
|
+
"liquid_rescale",
|
211
|
+
"list",
|
212
|
+
"loader",
|
213
|
+
"log",
|
214
|
+
"loop",
|
215
|
+
"lowlight_color",
|
216
|
+
"magnify",
|
217
|
+
"map",
|
218
|
+
"mattecolor",
|
219
|
+
"median",
|
220
|
+
"mean_shift",
|
221
|
+
"metric",
|
222
|
+
"mode",
|
223
|
+
"modulate",
|
224
|
+
"moments",
|
225
|
+
"monitor",
|
226
|
+
"monochrome",
|
227
|
+
"morph",
|
228
|
+
"morphology",
|
229
|
+
"mosaic",
|
230
|
+
"motion_blur",
|
231
|
+
"name",
|
232
|
+
"negate",
|
233
|
+
"noise",
|
234
|
+
"normalize",
|
235
|
+
"opaque",
|
236
|
+
"ordered_dither",
|
237
|
+
"orient",
|
238
|
+
"page",
|
239
|
+
"paint",
|
240
|
+
"pause",
|
241
|
+
"perceptible",
|
242
|
+
"ping",
|
243
|
+
"pointsize",
|
244
|
+
"polaroid",
|
245
|
+
"poly",
|
246
|
+
"posterize",
|
247
|
+
"precision",
|
248
|
+
"preview",
|
249
|
+
"process",
|
250
|
+
"quality",
|
251
|
+
"quantize",
|
252
|
+
"quiet",
|
253
|
+
"radial_blur",
|
254
|
+
"raise",
|
255
|
+
"random_threshold",
|
256
|
+
"range_threshold",
|
257
|
+
"red_primary",
|
258
|
+
"regard_warnings",
|
259
|
+
"region",
|
260
|
+
"remote",
|
261
|
+
"render",
|
262
|
+
"repage",
|
263
|
+
"resample",
|
264
|
+
"resize",
|
265
|
+
"resize_to_fill",
|
266
|
+
"resize_to_fit",
|
267
|
+
"resize_to_limit",
|
268
|
+
"resize_and_pad",
|
269
|
+
"respect_parentheses",
|
270
|
+
"reverse",
|
271
|
+
"roll",
|
272
|
+
"rotate",
|
273
|
+
"sample",
|
274
|
+
"sampling_factor",
|
275
|
+
"saver",
|
276
|
+
"scale",
|
277
|
+
"scene",
|
278
|
+
"screen",
|
279
|
+
"seed",
|
280
|
+
"segment",
|
281
|
+
"selective_blur",
|
282
|
+
"separate",
|
283
|
+
"sepia_tone",
|
284
|
+
"shade",
|
285
|
+
"shadow",
|
286
|
+
"shared_memory",
|
287
|
+
"sharpen",
|
288
|
+
"shave",
|
289
|
+
"shear",
|
290
|
+
"sigmoidal_contrast",
|
291
|
+
"silent",
|
292
|
+
"similarity_threshold",
|
293
|
+
"size",
|
294
|
+
"sketch",
|
295
|
+
"smush",
|
296
|
+
"snaps",
|
297
|
+
"solarize",
|
298
|
+
"sort_pixels",
|
299
|
+
"sparse_color",
|
300
|
+
"splice",
|
301
|
+
"spread",
|
302
|
+
"statistic",
|
303
|
+
"stegano",
|
304
|
+
"stereo",
|
305
|
+
"storage_type",
|
306
|
+
"stretch",
|
307
|
+
"strip",
|
308
|
+
"stroke",
|
309
|
+
"strokewidth",
|
310
|
+
"style",
|
311
|
+
"subimage_search",
|
312
|
+
"swap",
|
313
|
+
"swirl",
|
314
|
+
"synchronize",
|
315
|
+
"taint",
|
316
|
+
"text_font",
|
317
|
+
"threshold",
|
318
|
+
"thumbnail",
|
319
|
+
"tile_offset",
|
320
|
+
"tint",
|
321
|
+
"title",
|
322
|
+
"transform",
|
323
|
+
"transparent",
|
324
|
+
"transparent_color",
|
325
|
+
"transpose",
|
326
|
+
"transverse",
|
327
|
+
"treedepth",
|
328
|
+
"trim",
|
329
|
+
"type",
|
330
|
+
"undercolor",
|
331
|
+
"unique_colors",
|
332
|
+
"units",
|
333
|
+
"unsharp",
|
334
|
+
"update",
|
335
|
+
"valid_image",
|
336
|
+
"view",
|
337
|
+
"vignette",
|
338
|
+
"virtual_pixel",
|
339
|
+
"visual",
|
340
|
+
"watermark",
|
341
|
+
"wave",
|
342
|
+
"wavelet_denoise",
|
343
|
+
"weight",
|
344
|
+
"white_balance",
|
345
|
+
"white_point",
|
346
|
+
"white_threshold",
|
347
|
+
"window",
|
348
|
+
"window_group"
|
349
|
+
]
|
350
|
+
mattr_accessor :unsupported_image_processing_arguments
|
351
|
+
|
61
352
|
mattr_accessor :service_urls_expire_in, default: 5.minutes
|
62
353
|
|
63
354
|
mattr_accessor :routes_prefix, default: "/rails/active_storage"
|
@@ -67,6 +358,8 @@ module ActiveStorage
|
|
67
358
|
mattr_accessor :replace_on_assign_to_many, default: false
|
68
359
|
mattr_accessor :track_variants, default: false
|
69
360
|
|
361
|
+
mattr_accessor :video_preview_arguments, default: "-y -vframes 1 -f image2"
|
362
|
+
|
70
363
|
module Transformers
|
71
364
|
extend ActiveSupport::Autoload
|
72
365
|
|
@@ -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.6
|
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-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,84 +16,84 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 6.1.
|
19
|
+
version: 6.1.6
|
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.6
|
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.6
|
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.6
|
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.6
|
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.6
|
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.6
|
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.6
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: marcel
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0
|
75
|
+
version: '1.0'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0
|
82
|
+
version: '1.0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: mini_mime
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
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:
|
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,11 @@ 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.6/activestorage/CHANGELOG.md
|
192
|
+
documentation_uri: https://api.rubyonrails.org/v6.1.6/
|
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.6/activestorage
|
195
|
+
rubygems_mfa_required: 'true'
|
194
196
|
post_install_message:
|
195
197
|
rdoc_options: []
|
196
198
|
require_paths:
|
@@ -206,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
208
|
- !ruby/object:Gem::Version
|
207
209
|
version: '0'
|
208
210
|
requirements: []
|
209
|
-
rubygems_version: 3.
|
211
|
+
rubygems_version: 3.3.7
|
210
212
|
signing_key:
|
211
213
|
specification_version: 4
|
212
214
|
summary: Local and cloud file storage framework.
|