From ee962136074e4952bba6acaaaf32b72697a82f2e Mon Sep 17 00:00:00 2001 From: Daniel Roseman Date: Fri, 7 May 2021 09:25:23 +0100 Subject: [PATCH] Add presigned_url method. For GCS, return an actual presigned URL for the file. For disk, return a standard `file://` url. For inmemory, return the original URL, for the sake of completeness. --- lib/bucket_store/disk.rb | 6 ++++++ lib/bucket_store/gcs.rb | 4 ++++ lib/bucket_store/in_memory.rb | 6 ++++++ lib/bucket_store/key_storage.rb | 19 +++++++++++++++++++ spec/bucket_store/key_storage_spec.rb | 8 ++++++++ 5 files changed, 43 insertions(+) diff --git a/lib/bucket_store/disk.rb b/lib/bucket_store/disk.rb index 588470d..7f80f18 100644 --- a/lib/bucket_store/disk.rb +++ b/lib/bucket_store/disk.rb @@ -55,6 +55,12 @@ def delete!(bucket:, key:) true end + # rubocop: disable Lint/UnusedMethodArgument + def presigned_url(bucket:, key:, expiry:) + "file://#{key_path(bucket, key)}" + end + # rubocop: enable Lint/UnusedMethodArgument + private attr_reader :base_dir diff --git a/lib/bucket_store/gcs.rb b/lib/bucket_store/gcs.rb index 78492f1..3403217 100644 --- a/lib/bucket_store/gcs.rb +++ b/lib/bucket_store/gcs.rb @@ -66,6 +66,10 @@ def delete!(bucket:, key:) true end + def presigned_url(bucket:, key:, expiry:) + get_bucket(bucket).file(key).signed_url(expires: expiry) + end + private attr_reader :storage diff --git a/lib/bucket_store/in_memory.rb b/lib/bucket_store/in_memory.rb index 6dfccc9..221e4ec 100644 --- a/lib/bucket_store/in_memory.rb +++ b/lib/bucket_store/in_memory.rb @@ -58,5 +58,11 @@ def delete!(bucket:, key:) true end + + # rubocop: disable Lint/UnusedMethodArgument + def presigned_url(bucket:, key:, expiry:) + "inmemory://#{bucket}/#{key}" + end + # rubocop: enable Lint/UnusedMethodArgument end end diff --git a/lib/bucket_store/key_storage.rb b/lib/bucket_store/key_storage.rb index 90bedf5..a6dae0f 100644 --- a/lib/bucket_store/key_storage.rb +++ b/lib/bucket_store/key_storage.rb @@ -156,6 +156,25 @@ def exists? list.first == "#{adapter_type}://#{bucket}/#{key}" end + # Generates a pre-signed URL for the referenced key. + # + # @param [Integer] expiry The time to expiry for the URL; defaults to 24 hours. + # @return [String] The pre-signed URL + # + # @example Generate a presigned URL for a file + # BucketStore.for("gcs://bucket/file.txt").presigned_url + def presigned_url(expiry: 86400) + BucketStore.logger.info(event: "key_storage.presigned_url_started") + + start = BucketStore::Timing.monotonic_now + url = adapter.presigned_url(bucket: bucket, key: key, expiry: expiry) + + BucketStore.logger.info(event: "key_storage.presigned_url_finished", + duration: BucketStore::Timing.monotonic_now - start) + + url + end + private attr_reader :adapter diff --git a/spec/bucket_store/key_storage_spec.rb b/spec/bucket_store/key_storage_spec.rb index c41f65e..b2f8af2 100644 --- a/spec/bucket_store/key_storage_spec.rb +++ b/spec/bucket_store/key_storage_spec.rb @@ -154,4 +154,12 @@ def build_for(key) expect(build_for("inmemory://bucket/prefix/a").exists?).to be false end end + + describe "#presigned_url" do + let(:url) { "inmemory://bucket/file1" } + + it "returns a URL" do + expect(build_for(url).presigned_url).to eq(url) + end + end end