Skip to content

Commit

Permalink
Merge pull request #5 from DEFRA/add-presigned-url-method
Browse files Browse the repository at this point in the history
Implement pre-signed url method in the Bucket object
  • Loading branch information
cintamani committed Jun 7, 2019
2 parents dde4342 + 0bb532f commit 9cee098
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 15 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ end

## Usage

### Upload a file

```
file_to_upload = Tempfile.new("test-upload-file.csv")
bucket = DefraRuby::Aws.get_bucket("defra-ruby-aws")
Expand All @@ -58,6 +60,13 @@ else
end
```

### Generate a presigned URL for download

```
bucket = DefraRuby::Aws.get_bucket("defra-ruby-aws")
presigned_url = bucket.presigned_url("test-upload-file.csv")
```

## Contributing to this project

If you have an idea you'd like to contribute please log an issue.
Expand Down
2 changes: 2 additions & 0 deletions lib/defra_ruby/aws.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
require_relative "aws/response"
require_relative "aws/configuration"

require_relative "aws/services/concerns/has_aws_bucket_configuration"
require_relative "aws/services/bucket_loader_service"
require_relative "aws/services/presigned_url_service"

module DefraRuby
module Aws
Expand Down
4 changes: 4 additions & 0 deletions lib/defra_ruby/aws/bucket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ def load(file)
BucketLoaderService.run(self, file)
end

def presigned_url(file_name)
PresignedUrlService.run(self, file_name)
end

private

attr_writer :region
Expand Down
17 changes: 2 additions & 15 deletions lib/defra_ruby/aws/services/bucket_loader_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
module DefraRuby
module Aws
class BucketLoaderService
include HasAwsBucketConfiguration

def self.run(bucket, file)
new(bucket, file).run
end
Expand All @@ -20,21 +22,6 @@ def run

attr_reader :bucket, :file

def s3_bucket
s3.bucket(bucket.bucket_name)
end

def s3
::Aws::S3::Resource.new(
region: bucket.region,
credentials: aws_credentials
)
end

def aws_credentials
::Aws::Credentials.new(bucket.access_key_id, bucket.secret_access_key)
end

def response_exe
lambda do
s3_bucket.object(File.basename(file.path)).upload_file(file.path, server_side_encryption: :AES256)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module DefraRuby
module Aws
module HasAwsBucketConfiguration
def s3_bucket
s3.bucket(bucket.bucket_name)
end

def s3
::Aws::S3::Resource.new(
region: bucket.region,
credentials: aws_credentials
)
end

def aws_credentials
::Aws::Credentials.new(bucket.access_key_id, bucket.secret_access_key)
end
end
end
end
32 changes: 32 additions & 0 deletions lib/defra_ruby/aws/services/presigned_url_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

module DefraRuby
module Aws
class PresignedUrlService
include HasAwsBucketConfiguration

def self.run(bucket, file_name)
new(bucket, file_name).run
end

def initialize(bucket, file_name)
@bucket = bucket
@file_name = file_name
end

def run
s3_bucket.object(file_name).presigned_url(
:get,
expires_in: 20 * 60, # 20 minutes in seconds
secure: true,
response_content_type: "text/csv",
response_content_disposition: "attachment; filename=#{file_name}"
)
end

private

attr_reader :bucket, :file_name
end
end
end
32 changes: 32 additions & 0 deletions spec/lib/defra_ruby/aws/services/presigned_url_service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true

require "spec_helper"

module DefraRuby
module Aws
RSpec.describe PresignedUrlService do
describe ".run" do
let(:configs) do
{
name: "test",
credentials: {
access_key_id: "123",
secret_access_key: "Secret"
}
}
end
let(:bucket) { Bucket.new(configs) }
let(:presigned_url) { described_class.run(bucket, "testfile.csv") }

it "returns a presigned url for a given file in the bucket" do
expect(presigned_url).to include("https://test.s3.eu-west-1.amazonaws.com/testfile.csv")
expect(presigned_url).to include("response-content-disposition=attachment")
expect(presigned_url).to include("response-content-type=text%2Fcsv")
expect(presigned_url).to include("Amz-Expires")
expect(presigned_url).to include("Amz-Credential")
expect(presigned_url).to include("Amz-Signature")
end
end
end
end
end

0 comments on commit 9cee098

Please sign in to comment.