Created
December 29, 2017 17:27
-
-
Save onnimonni/013331a23755d29406f9e5cd3edf1eeb to your computer and use it in GitHub Desktop.
Ruby script to upload versioned private files to s3 bucket and to retrieve their presigned_url. This can be used to achieve append only file uploads which can't be deleted easily.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'aws-sdk-s3' | |
# When there's something wrong with the s3 | |
class S3StorageError < StandardError | |
def initialize(data) | |
@data = data | |
end | |
end | |
class S3File | |
def initialize(params) | |
# Bucket info | |
@bucket = params[:bucket] || ENV['AWS_S3_BUCKET_NAME'] || raise(S3StorageError,'You need to provide :bucket or AWS_S3_BUCKET_NAME') | |
# AWS credentials | |
@client = Aws::S3::Client.new( | |
region: param[:region] || ENV['AWS_DEFAULT_REGION'] || 'eu-central-1', | |
access_key_id: param[:access_key_id] || ENV['AWS_ACCESS_KEY_ID'] || raise(S3StorageError,'You need to provide :access_key_id or AWS_ACCESS_KEY_ID'), | |
secret_access_key: param[:secret_access_key] || ENV['AWS_SECRET_ACCESS_KEY'] || raise(S3StorageError,'You need to provide :secret_access_key or AWS_SECRET_ACCESS_KEY') | |
) | |
# This is used to get the secret url to private files | |
@signer = Aws::S3::Presigner.new(client: client) | |
# These are needed in order to find the file | |
@path = params[:path] | |
@version_id = params[:version_id] | |
# Saves the file into s3 | |
def save(params) | |
raise S3StorageError "@path for file is not defined!" unless @path | |
request = defaults.merge(params) | |
raise S3StorageError "Can't define :content and :file into same object" if request[:content] && request[:file] | |
if request[:content] | |
response = s3.put_object(request) | |
elsif request[:file] | |
# Stream the file into s3 | |
filename = request.delete(:file) | |
File.open(filename, 'rb') do |file_contents| | |
response = s3.put_object( request.merge({ body: file_contents }) ) | |
end | |
end | |
# This is the version which is interesting to us | |
@version_id = resp.version_id | |
end | |
# Gets presigned url which will expire automatically | |
def presigned_url(params) | |
signer.presigned_url( defaults.merge(params) ) | |
end | |
private | |
# Default settings | |
def defaults | |
{ | |
acl: 'private', | |
expires_in: 15.minutes.to_i | |
bucket: @bucket, | |
path: @path | |
} | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment