aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activestorage/app/models/active_storage/blob.rb4
-rw-r--r--activestorage/app/models/active_storage/filename.rb8
-rw-r--r--activestorage/test/models/blob_test.rb2
-rw-r--r--activesupport/test/core_ext/duration_test.rb1
-rw-r--r--guides/source/configuring.md35
-rw-r--r--railties/lib/rails/commands/credentials/credentials_command.rb2
-rw-r--r--railties/lib/rails/commands/encrypted/encrypted_command.rb3
-rw-r--r--railties/test/commands/credentials_test.rb12
-rw-r--r--railties/test/commands/encrypted_test.rb12
9 files changed, 76 insertions, 3 deletions
diff --git a/activestorage/app/models/active_storage/blob.rb b/activestorage/app/models/active_storage/blob.rb
index 892a833fae..a1e69e2264 100644
--- a/activestorage/app/models/active_storage/blob.rb
+++ b/activestorage/app/models/active_storage/blob.rb
@@ -109,7 +109,9 @@ class ActiveStorage::Blob < ActiveRecord::Base
# with users. Instead, the +service_url+ should only be exposed as a redirect from a stable, possibly authenticated URL.
# Hiding the +service_url+ behind a redirect also gives you the power to change services without updating all URLs. And
# it allows permanent URLs that redirect to the +service_url+ to be cached in the view.
- def service_url(expires_in: service.url_expires_in, disposition: :inline, filename: self.filename, **options)
+ def service_url(expires_in: service.url_expires_in, disposition: :inline, filename: nil, **options)
+ filename = ActiveStorage::Filename.wrap(filename || self.filename)
+
service.url key, expires_in: expires_in, filename: filename, content_type: content_type,
disposition: forcibly_serve_as_binary? ? :attachment : disposition, **options
end
diff --git a/activestorage/app/models/active_storage/filename.rb b/activestorage/app/models/active_storage/filename.rb
index b9413dec95..2b8880716e 100644
--- a/activestorage/app/models/active_storage/filename.rb
+++ b/activestorage/app/models/active_storage/filename.rb
@@ -5,6 +5,14 @@
class ActiveStorage::Filename
include Comparable
+ class << self
+ # Returns a Filename instance based on the given filename. If the filename is a Filename, it is
+ # returned unmodified. If it is a String, it is passed to ActiveStorage::Filename.new.
+ def wrap(filename)
+ filename.kind_of?(self) ? filename : new(filename)
+ end
+ end
+
def initialize(filename)
@filename = filename
end
diff --git a/activestorage/test/models/blob_test.rb b/activestorage/test/models/blob_test.rb
index 5cd2a94326..9b555f9a1d 100644
--- a/activestorage/test/models/blob_test.rb
+++ b/activestorage/test/models/blob_test.rb
@@ -82,6 +82,8 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase
freeze_time do
assert_equal expected_url_for(blob), blob.service_url
assert_equal expected_url_for(blob, filename: new_filename), blob.service_url(filename: new_filename)
+ assert_equal expected_url_for(blob, filename: new_filename), blob.service_url(filename: "new.txt")
+ assert_equal expected_url_for(blob, filename: blob.filename), blob.service_url(filename: nil)
end
end
diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb
index be33324f25..c5022cf5b1 100644
--- a/activesupport/test/core_ext/duration_test.rb
+++ b/activesupport/test/core_ext/duration_test.rb
@@ -5,6 +5,7 @@ require "active_support/inflector"
require "active_support/time"
require "active_support/json"
require "time_zone_test_helpers"
+require "yaml"
class DurationTest < ActiveSupport::TestCase
include TimeZoneTestHelpers
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index a0bf6046da..b0f39e7ab5 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -752,6 +752,41 @@ main application.
You can set this as nil to not mount Action Cable as part of your
normal Rails server.
+
+### Configuring Active Storage
+
+`config.active_storage` provides the following configuration options:
+
+* `config.active_storage.analyzers` accepts an array of classes indicating the analyzers available for Active Storage blobs. The default is `[ActiveStorage::Analyzer::ImageAnalyzer, ActiveStorage::Analyzer::VideoAnalyzer]`. The former can extract width and height of an image blob; the latter can extract width, height, duration, angle, and aspect ratio of a video blob.
+
+* `config.active_storage.previewers` accepts an array of classes indicating the image previewers available in Active Storage blobs. The default is `[ActiveStorage::Previewer::PDFPreviewer, ActiveStorage::Previewer::VideoPreviewer]`. The former can generate a thumbnail from the first page of a PDF blob; the latter from the relevant frame of a video blob.
+
+* `config.active_storage.paths` accepts a hash of options indicating the locations of previewer/analyzer commands. The default is `{}`, meaning the commands will be looked for in the default path. Can include any of these options:
+ * `:ffprobe` - The location of the ffprobe executable.
+ * `:mutool` - The location of the mutool executable.
+ * `:ffmpeg` - The location of the ffmpeg executable.
+
+ ```ruby
+ config.active_storage.paths[:ffprobe] = '/usr/local/bin/ffprobe'
+ ```
+
+* `config.active_storage.variable_content_types` accepts an array of strings indicating the content types that Active Storage can transform through ImageMagick. The default is `%w(image/png image/gif image/jpg image/jpeg image/vnd.adobe.photoshop)`.
+
+* `config.active_storage.content_types_to_serve_as_binary` accepts an array of strings indicating the content types that Active Storage will always serve as an attachment, rather than inline. The default is `%w(text/html
+text/javascript image/svg+xml application/postscript application/x-shockwave-flash text/xml application/xml application/xhtml+xml)`.
+
+* `config.active_storage.queue` can be used to set the name of the Active Job queue used to perform jobs like analyzing the content of a blob or purging a blog.
+
+ ```ruby
+ config.active_job.queue = :low_priority
+ ```
+
+* `config.active_storage.logger` can be used to set the logger used by Active Storage. Accepts a logger conforming to the interface of Log4r or the default Ruby Logger class.
+
+ ```ruby
+ config.active_job.logger = ActiveSupport::Logger.new(STDOUT)
+ ```
+
### Configuring a Database
Just about every Rails application will interact with a database. You can connect to the database by setting an environment variable `ENV['DATABASE_URL']` or by using a configuration file called `config/database.yml`.
diff --git a/railties/lib/rails/commands/credentials/credentials_command.rb b/railties/lib/rails/commands/credentials/credentials_command.rb
index 385d3976da..fa54c0362a 100644
--- a/railties/lib/rails/commands/credentials/credentials_command.rb
+++ b/railties/lib/rails/commands/credentials/credentials_command.rb
@@ -20,7 +20,7 @@ module Rails
require_application_and_environment!
ensure_editor_available(command: "bin/rails credentials:edit") || (return)
- ensure_master_key_has_been_added
+ ensure_master_key_has_been_added if Rails.application.credentials.key.nil?
ensure_credentials_have_been_added
catch_editing_exceptions do
diff --git a/railties/lib/rails/commands/encrypted/encrypted_command.rb b/railties/lib/rails/commands/encrypted/encrypted_command.rb
index 912c453f09..3bc8f76ce4 100644
--- a/railties/lib/rails/commands/encrypted/encrypted_command.rb
+++ b/railties/lib/rails/commands/encrypted/encrypted_command.rb
@@ -21,9 +21,10 @@ module Rails
def edit(file_path)
require_application_and_environment!
+ encrypted = Rails.application.encrypted(file_path, key_path: options[:key])
ensure_editor_available(command: "bin/rails encrypted:edit") || (return)
- ensure_encryption_key_has_been_added(options[:key])
+ ensure_encryption_key_has_been_added(options[:key]) if encrypted.key.nil?
ensure_encrypted_file_has_been_added(file_path, options[:key])
catch_editing_exceptions do
diff --git a/railties/test/commands/credentials_test.rb b/railties/test/commands/credentials_test.rb
index 7c464b3fde..663ee73bcd 100644
--- a/railties/test/commands/credentials_test.rb
+++ b/railties/test/commands/credentials_test.rb
@@ -43,6 +43,18 @@ class Rails::Command::CredentialsCommandTest < ActiveSupport::TestCase
assert_match(/api_key: abc/, run_show_command)
end
+ test "edit command does not add master key when `RAILS_MASTER_KEY` env specified" do
+ Dir.chdir(app_path) do
+ key = IO.binread("config/master.key").strip
+ FileUtils.rm("config/master.key")
+
+ switch_env("RAILS_MASTER_KEY", key) do
+ run_edit_command
+ assert_not File.exist?("config/master.key")
+ end
+ end
+ end
+
test "show credentials" do
assert_match(/access_key_id: 123/, run_show_command)
end
diff --git a/railties/test/commands/encrypted_test.rb b/railties/test/commands/encrypted_test.rb
index 6647dcc902..9fc73d5f18 100644
--- a/railties/test/commands/encrypted_test.rb
+++ b/railties/test/commands/encrypted_test.rb
@@ -33,6 +33,18 @@ class Rails::Command::EncryptedCommandTest < ActiveSupport::TestCase
end
end
+ test "edit command does not add master key when `RAILS_MASTER_KEY` env specified" do
+ Dir.chdir(app_path) do
+ key = IO.binread("config/master.key").strip
+ FileUtils.rm("config/master.key")
+
+ switch_env("RAILS_MASTER_KEY", key) do
+ run_edit_command("config/tokens.yml.enc")
+ assert_not File.exist?("config/master.key")
+ end
+ end
+ end
+
test "edit encrypts file with custom key" do
run_edit_command("config/tokens.yml.enc", key: "config/tokens.key")