Skip to content

Instantly share code, notes, and snippets.

@jeshuaborges
Created February 6, 2013 22:38
Show Gist options
  • Save jeshuaborges/4726557 to your computer and use it in GitHub Desktop.
Save jeshuaborges/4726557 to your computer and use it in GitHub Desktop.
require 'securerandom'
require 'active_support/json'
require 'active_support/core_ext/numeric/time'
require 'active_support/core_ext/numeric/bytes'
require 'active_support/core_ext/object/to_json'
class AWSPolicy
attr_reader :expiration, :path
class << self
CONFIG_KEYS = [:access_key_id, :secret_access_key, :bucket]
attr_accessor *CONFIG_KEYS
def configure
yield self
end
def assert_config!
CONFIG_KEYS.each do |config|
raise ArgumentError, "Missing configuration '#{config}'" unless self.send(config)
end
end
end
def initialize(config={})
@path = config.fetch(:path) { "uploads/#{SecureRandom.hex}" }
@expiration = config.fetch(:expiration) { 10.hours.from_now }
@max_file_size = config.fetch(:expiration) { 100.megabytes }
end
def fields
self.class.assert_config!
{
key: key,
acl: acl,
policy: policy,
signature: signature,
AWSAccessKeyId: self.class.access_key_id
}
end
def url
"https://#{self.bucket}.s3.amazonaws.com/"
end
protected
def key
"#{path}/${filename}"
end
def acl
'public-read'
end
def policy
Base64.encode64(policy_data.to_json).gsub("\n", "")
end
def policy_data
{
expiration: expiration,
conditions: [
['starts-with', '$key', 'uploads/'],
['content-length-range', 0, self.class.max_file_size],
{bucket: self.class.bucket},
{acl: acl}
]
}
end
def signature
Base64.encode64(
OpenSSL::HMAC.digest(
OpenSSL::Digest::Digest.new('sha1'),
self.class.secret_access_key, policy
)
).gsub("\n", "")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment