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]: be11d1b6e8/activerecord/lib/active_record/signed_id.rb (L42-L48)
This commit is contained in:
Daniel Colson 2020-12-03 12:36:52 -05:00 committed by GitHub
parent cafdd18721
commit 8ef5bd9ced
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 4 deletions

View File

@ -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

View File

@ -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)