aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/active_storage/blobs_controller.rb22
-rw-r--r--config/routes.rb8
2 files changed, 30 insertions, 0 deletions
diff --git a/app/controllers/active_storage/blobs_controller.rb b/app/controllers/active_storage/blobs_controller.rb
new file mode 100644
index 0000000000..5a527d0a33
--- /dev/null
+++ b/app/controllers/active_storage/blobs_controller.rb
@@ -0,0 +1,22 @@
+# Take a signed permanent reference for a blob and turn it into an expiring service URL for its download.
+# Note: These URLs are publicly accessible. If you need to enforce access protection beyond the
+# security-through-obscurity factor of the signed blob references, you'll need to implement your own
+# authenticated redirection controller.
+class ActiveStorage::BlobsController < ActionController::Base
+ def show
+ if blob = find_signed_blob
+ redirect_to blob.url(disposition: disposition_param)
+ else
+ head :not_found
+ end
+ end
+
+ private
+ def find_signed_blob
+ ActiveStorage::Blob.find_signed(params[:signed_id])
+ end
+
+ def disposition_param
+ params[:disposition].presence_in(%w( inline attachment )) || "inline"
+ end
+end
diff --git a/config/routes.rb b/config/routes.rb
index 78fa0e707b..b368e35cac 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,4 +1,12 @@
Rails.application.routes.draw do
+ get "/rails/active_storage/blobs/:signed_id/*filename" => "active_storage/blobs#show", as: :rails_service_blob
+
+ direct :rails_blob do |blob|
+ route_for(:rails_service_blob, blob.signed_id, blob.filename)
+ end
+
+ resolve("ActiveStorage::Blob") { |blob| route_for(:rails_blob, blob) }
+ resolve("ActiveStorage::Attachment") { |attachment| route_for(:rails_blob, attachment.blob) }
get "/rails/active_storage/variants/:signed_blob_id/:variation_key/*filename" => "active_storage/variants#show", as: :rails_blob_variation