Add expires_at
option to ActiveStorage::Blob#signed_id
This commit is contained in:
parent
5fcc61076d
commit
1f9fbbe213
@ -1,3 +1,12 @@
|
||||
* Add `expires_at` option to `ActiveStorage::Blob#signed_id`.
|
||||
|
||||
```ruby
|
||||
rails_blob_path(user.avatar, disposition: "attachment", expires_at: 30.minutes.from_now)
|
||||
<%= image_tag rails_blob_path(user.avatar.variant(resize: "100x100"), expires_at: 30.minutes.from_now) %>
|
||||
```
|
||||
|
||||
*Aki*
|
||||
|
||||
* Allow attaching File and Pathname when assigning attributes, e.g.
|
||||
|
||||
```ruby
|
||||
|
@ -158,7 +158,7 @@ def compose(blobs, filename:, content_type: nil, metadata: nil)
|
||||
end
|
||||
|
||||
# Returns a signed ID for this blob that's suitable for reference on the client-side without fear of tampering.
|
||||
def signed_id(purpose: :blob_id, expires_in: nil)
|
||||
def signed_id(purpose: :blob_id, expires_in: nil, expires_at: nil)
|
||||
super
|
||||
end
|
||||
|
||||
|
@ -32,16 +32,17 @@
|
||||
|
||||
direct :rails_storage_proxy do |model, options|
|
||||
expires_in = options.delete(:expires_in) { ActiveStorage.urls_expire_in }
|
||||
expires_at = options.delete(:expires_at)
|
||||
|
||||
if model.respond_to?(:signed_id)
|
||||
route_for(
|
||||
:rails_service_blob_proxy,
|
||||
model.signed_id(expires_in: expires_in),
|
||||
model.signed_id(expires_in: expires_in, expires_at: expires_at),
|
||||
model.filename,
|
||||
options
|
||||
)
|
||||
else
|
||||
signed_blob_id = model.blob.signed_id(expires_in: expires_in)
|
||||
signed_blob_id = model.blob.signed_id(expires_in: expires_in, expires_at: expires_at)
|
||||
variation_key = model.variation.key
|
||||
filename = model.blob.filename
|
||||
|
||||
@ -57,16 +58,17 @@
|
||||
|
||||
direct :rails_storage_redirect do |model, options|
|
||||
expires_in = options.delete(:expires_in) { ActiveStorage.urls_expire_in }
|
||||
expires_at = options.delete(:expires_at)
|
||||
|
||||
if model.respond_to?(:signed_id)
|
||||
route_for(
|
||||
:rails_service_blob,
|
||||
model.signed_id(expires_in: expires_in),
|
||||
model.signed_id(expires_in: expires_in, expires_at: expires_at),
|
||||
model.filename,
|
||||
options
|
||||
)
|
||||
else
|
||||
signed_blob_id = model.blob.signed_id(expires_in: expires_in)
|
||||
signed_blob_id = model.blob.signed_id(expires_in: expires_in, expires_at: expires_at)
|
||||
variation_key = model.variation.key
|
||||
filename = model.blob.filename
|
||||
|
||||
|
@ -32,18 +32,30 @@ class ActiveStorage::Blobs::ProxyControllerTest < ActionDispatch::IntegrationTes
|
||||
assert_match(/^attachment; /, response.headers["Content-Disposition"])
|
||||
end
|
||||
|
||||
test "signed ID within expiration date" do
|
||||
test "signed ID within expiration duration" do
|
||||
get rails_storage_proxy_url(create_file_blob(filename: "racecar.jpg"), expires_in: 1.minute)
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "Expired signed ID" do
|
||||
test "Expired signed ID within expiration duration" do
|
||||
url = rails_storage_proxy_url(create_file_blob(filename: "racecar.jpg"), expires_in: 1.minute)
|
||||
travel 2.minutes
|
||||
get url
|
||||
assert_response :not_found
|
||||
end
|
||||
|
||||
test "signed ID within expiration time" do
|
||||
get rails_storage_proxy_url(create_file_blob(filename: "racecar.jpg"), expires_at: 1.minute.from_now)
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "Expired signed ID within expiration time" do
|
||||
url = rails_storage_proxy_url(create_file_blob(filename: "racecar.jpg"), expires_at: 1.minute.from_now)
|
||||
travel 2.minutes
|
||||
get url
|
||||
assert_response :not_found
|
||||
end
|
||||
|
||||
test "single Byte Range" do
|
||||
get rails_storage_proxy_url(create_file_blob(filename: "racecar.jpg")), headers: { "Range" => "bytes=5-9" }
|
||||
assert_response :partial_content
|
||||
|
@ -19,17 +19,29 @@ class ActiveStorage::Blobs::RedirectControllerTest < ActionDispatch::Integration
|
||||
assert_equal "max-age=300, private", response.headers["Cache-Control"]
|
||||
end
|
||||
|
||||
test "signed ID within expiration date" do
|
||||
test "signed ID within expiration duration" do
|
||||
get rails_storage_redirect_url(@blob, expires_in: 1.minute)
|
||||
assert_redirected_to(/racecar\.jpg/)
|
||||
end
|
||||
|
||||
test "Expired signed ID" do
|
||||
test "Expired signed ID within expiration duration" do
|
||||
url = rails_storage_redirect_url(@blob, expires_in: 1.minute)
|
||||
travel 2.minutes
|
||||
get url
|
||||
assert_response :not_found
|
||||
end
|
||||
|
||||
test "signed ID within expiration time" do
|
||||
get rails_storage_redirect_url(@blob, expires_at: 1.minute.from_now)
|
||||
assert_redirected_to(/racecar\.jpg/)
|
||||
end
|
||||
|
||||
test "Expired signed ID within expiration time" do
|
||||
url = rails_storage_redirect_url(@blob, expires_at: 1.minute.from_now)
|
||||
travel 2.minutes
|
||||
get url
|
||||
assert_response :not_found
|
||||
end
|
||||
end
|
||||
|
||||
class ActiveStorage::Blobs::ExpiringRedirectControllerTest < ActionDispatch::IntegrationTest
|
||||
|
@ -108,7 +108,7 @@ class ActiveStorage::AttachmentTest < ActiveSupport::TestCase
|
||||
assert_equal blob, ActiveStorage::Blob.find_signed!(signed_id)
|
||||
end
|
||||
|
||||
test "fail to find blob within expiration date" do
|
||||
test "fail to find blob within expiration duration" do
|
||||
blob = create_blob
|
||||
@user.avatar.attach(blob)
|
||||
|
||||
@ -117,6 +117,23 @@ class ActiveStorage::AttachmentTest < ActiveSupport::TestCase
|
||||
assert_nil ActiveStorage::Blob.find_signed(signed_id)
|
||||
end
|
||||
|
||||
test "getting a signed blob ID from an attachment with a expires_at" do
|
||||
blob = create_blob
|
||||
@user.avatar.attach(blob)
|
||||
|
||||
signed_id = @user.avatar.signed_id(expires_at: 1.minute.from_now)
|
||||
assert_equal blob, ActiveStorage::Blob.find_signed!(signed_id)
|
||||
end
|
||||
|
||||
test "fail to find blob within expiration time" do
|
||||
blob = create_blob
|
||||
@user.avatar.attach(blob)
|
||||
|
||||
signed_id = @user.avatar.signed_id(expires_at: 1.minute.from_now)
|
||||
travel 2.minutes
|
||||
assert_nil ActiveStorage::Blob.find_signed(signed_id)
|
||||
end
|
||||
|
||||
test "signed blob ID backwards compatibility" do
|
||||
blob = create_blob
|
||||
@user.avatar.attach(blob)
|
||||
|
Loading…
Reference in New Issue
Block a user