From 8ef5bd9ced351162b673904a0b77c7034ca2bc20 Mon Sep 17 00:00:00 2001 From: Daniel Colson Date: Thu, 3 Dec 2020 12:36:52 -0500 Subject: [PATCH] Allow custom purpose for ActiveStorage signed IDs This commit allows passing a custom `purpose:` keyword argument to both `find_signed!` and `signed_id`. This matches the signature of the `super` methods in ActiveRecord, and it is already possible with the non-bang [`find_signed`][find_signed] method, since that one doesn't have an override in ActiveStorage (although perhaps it should, to set the default :blob_id purpose) This is useful in cases where you want to further isolate different types of blobs, for example if they have different levels of authorization. [find_signed]: https://github.com/rails/rails/blob/be11d1b6e8853e25fd10f31f1d6422a2c58c06cf/activerecord/lib/active_record/signed_id.rb#L42-L48 --- activestorage/app/models/active_storage/blob.rb | 8 ++++---- activestorage/test/models/attachment_test.rb | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/activestorage/app/models/active_storage/blob.rb b/activestorage/app/models/active_storage/blob.rb index 18c8c9973a..086a2714bc 100644 --- a/activestorage/app/models/active_storage/blob.rb +++ b/activestorage/app/models/active_storage/blob.rb @@ -74,8 +74,8 @@ class ActiveStorage::Blob < ActiveStorage::Record # that was created ahead of the upload itself on form submission. # # The signed ID is also used to create stable URLs for the blob through the BlobsController. - def find_signed!(id, record: nil) - super(id, purpose: :blob_id) + def find_signed!(id, record: nil, purpose: :blob_id) + super(id, purpose: purpose) end def build_after_upload(io:, filename:, content_type: nil, metadata: nil, service_name: nil, identify: true, record: nil) #:nodoc: @@ -143,8 +143,8 @@ class ActiveStorage::Blob < ActiveStorage::Record end # Returns a signed ID for this blob that's suitable for reference on the client-side without fear of tampering. - def signed_id - super(purpose: :blob_id) + def signed_id(purpose: :blob_id) + super end # Returns the key pointing to the file on the service that's associated with this blob. The key is the diff --git a/activestorage/test/models/attachment_test.rb b/activestorage/test/models/attachment_test.rb index 3cd9ee3a07..949c179cfd 100644 --- a/activestorage/test/models/attachment_test.rb +++ b/activestorage/test/models/attachment_test.rb @@ -91,6 +91,14 @@ class ActiveStorage::AttachmentTest < ActiveSupport::TestCase assert_equal blob, ActiveStorage::Blob.find_signed!(signed_id) end + test "getting a signed blob ID from an attachment with a custom purpose" do + blob = create_blob + @user.avatar.attach(blob) + + signed_id = @user.avatar.signed_id(purpose: :custom_purpose) + assert_equal blob, ActiveStorage::Blob.find_signed!(signed_id, purpose: :custom_purpose) + end + test "signed blob ID backwards compatibility" do blob = create_blob @user.avatar.attach(blob)