mirror of
https://github.com/fog/fog-aws.git
synced 2022-11-09 13:50:52 -05:00
[AWS|Storage] signed_url should use v2 signature when aws_signature_version is 2
This commit is contained in:
parent
da2a4adc30
commit
becea65ad8
3 changed files with 69 additions and 16 deletions
1
Gemfile
1
Gemfile
|
@ -2,6 +2,5 @@ source 'https://rubygems.org'
|
||||||
|
|
||||||
# Specify your gem's dependencies in fog-aws.gemspec
|
# Specify your gem's dependencies in fog-aws.gemspec
|
||||||
gemspec
|
gemspec
|
||||||
|
|
||||||
gem 'pry-nav', group: :test
|
gem 'pry-nav', group: :test
|
||||||
gem "codeclimate-test-reporter", group: :test, require: nil
|
gem "codeclimate-test-reporter", group: :test, require: nil
|
||||||
|
|
|
@ -141,9 +141,28 @@ module Fog
|
||||||
|
|
||||||
def signed_url(params, expires)
|
def signed_url(params, expires)
|
||||||
#convert expires from a point in time to a delta to now
|
#convert expires from a point in time to a delta to now
|
||||||
|
expires = expires.to_i
|
||||||
|
if @signature_version == 4
|
||||||
|
params = v4_signed_params_for_url(params, expires)
|
||||||
|
else
|
||||||
|
params = v2_signed_params_for_url(params, expires)
|
||||||
|
end
|
||||||
|
|
||||||
|
params_to_url(params)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def validate_signature_version!
|
||||||
|
unless @signature_version == 2 || @signature_version == 4
|
||||||
|
raise "Unknown signature version #{@signature_version}; valid versions are 2 or 4"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def v4_signed_params_for_url(params, expires)
|
||||||
now = Fog::Time.now
|
now = Fog::Time.now
|
||||||
|
|
||||||
expires = expires.to_i - now.to_i
|
expires = expires - now.to_i
|
||||||
params[:headers] ||= {}
|
params[:headers] ||= {}
|
||||||
|
|
||||||
params[:query]||= {}
|
params[:query]||= {}
|
||||||
|
@ -157,14 +176,29 @@ module Fog
|
||||||
params = request_params(params)
|
params = request_params(params)
|
||||||
params[:headers][:host] = params[:host]
|
params[:headers][:host] = params[:host]
|
||||||
|
|
||||||
signature = @signer.signature_parameters(params, now, "UNSIGNED-PAYLOAD")
|
signature_query_params = @signer.signature_parameters(params, now, "UNSIGNED-PAYLOAD")
|
||||||
|
params[:query] = (params[:query] || {}).merge(signature_query_params)
|
||||||
params[:query] = (params[:query] || {}).merge(signature)
|
params
|
||||||
|
|
||||||
params_to_url(params)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
def v2_signed_params_for_url(params, expires)
|
||||||
|
if @aws_session_token
|
||||||
|
params[:headers]||= {}
|
||||||
|
params[:headers]['x-amz-security-token'] = @aws_session_token
|
||||||
|
end
|
||||||
|
signature = signature_v2(params, expires)
|
||||||
|
|
||||||
|
params = request_params(params)
|
||||||
|
|
||||||
|
signature_query_params = {
|
||||||
|
'AWSAccessKeyId' => @aws_access_key_id,
|
||||||
|
'Signature' => signature,
|
||||||
|
'Expires' => expires,
|
||||||
|
}
|
||||||
|
params[:query] = (params[:query] || {}).merge(signature_query_params)
|
||||||
|
params[:query]['x-amz-security-token'] = @aws_session_token if @aws_session_token
|
||||||
|
params
|
||||||
|
end
|
||||||
|
|
||||||
def region_to_host(region=nil)
|
def region_to_host(region=nil)
|
||||||
case region.to_s
|
case region.to_s
|
||||||
|
@ -377,6 +411,8 @@ module Fog
|
||||||
@port = options[:port] || DEFAULT_SCHEME_PORT[@scheme]
|
@port = options[:port] || DEFAULT_SCHEME_PORT[@scheme]
|
||||||
end
|
end
|
||||||
@path_style = options[:path_style] || false
|
@path_style = options[:path_style] || false
|
||||||
|
@signature_version = options.fetch(:aws_signature_version, 4)
|
||||||
|
validate_signature_version!
|
||||||
setup_credentials(options)
|
setup_credentials(options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -396,6 +432,11 @@ module Fog
|
||||||
|
|
||||||
@signer = Fog::AWS::SignatureV4.new( @aws_access_key_id, @aws_secret_access_key, @region, 's3')
|
@signer = Fog::AWS::SignatureV4.new( @aws_access_key_id, @aws_secret_access_key, @region, 's3')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def signature_v2(params, expires)
|
||||||
|
'foo'
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class Real
|
class Real
|
||||||
|
@ -451,11 +492,6 @@ module Fog
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def validate_signature_version!
|
|
||||||
unless @signature_version == 2 || @signature_version == 4
|
|
||||||
raise "Unknown signature version #{@signature_version}; valid versions are 2 or 4"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def setup_credentials(options)
|
def setup_credentials(options)
|
||||||
@aws_access_key_id = options[:aws_access_key_id]
|
@aws_access_key_id = options[:aws_access_key_id]
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
Shindo.tests('AWS | url', ["aws"]) do
|
Shindo.tests('AWS | url', ["aws"]) do
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,11 +13,30 @@ Shindo.tests('AWS | url', ["aws"]) do
|
||||||
|
|
||||||
now = Fog::Time.now
|
now = Fog::Time.now
|
||||||
if RUBY_VERSION > '1.8.7' # ruby 1.8.x doesn't provide hash ordering
|
if RUBY_VERSION > '1.8.7' # ruby 1.8.x doesn't provide hash ordering
|
||||||
tests('#url w/ response-cache-control').returns(
|
tests('#v4 url w/ response-cache-control').returns(
|
||||||
"https://fognonbucket.s3.amazonaws.com/test.txt?response-cache-control=No-cache&X-Amz-Expires=500&X-Amz-Date=#{now.to_iso8601_basic}&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=123/#{now.utc.strftime('%Y%m%d')}/us-east-1/s3/aws4_request&X-Amz-SignedHeaders=host&X-Amz-Signature="
|
"https://fognonbucket.s3.amazonaws.com/test.txt?response-cache-control=No-cache&X-Amz-Expires=500&X-Amz-Date=#{now.to_iso8601_basic}&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=123/#{now.utc.strftime('%Y%m%d')}/us-east-1/s3/aws4_request&X-Amz-SignedHeaders=host&X-Amz-Signature="
|
||||||
) do
|
) do
|
||||||
|
|
||||||
@file.url(Time.now + 500, :query => { 'response-cache-control' => 'No-cache' }).gsub(/(X-Amz-Signature=)[0-9a-f]+\z/,'\\1')
|
@file.url(now + 500, :query => { 'response-cache-control' => 'No-cache' }).gsub(/(X-Amz-Signature=)[0-9a-f]+\z/,'\\1')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@storage = Fog::Storage.new(
|
||||||
|
:provider => 'AWS',
|
||||||
|
:aws_access_key_id => '123',
|
||||||
|
:aws_secret_access_key => 'abc',
|
||||||
|
:aws_signature_version => 2,
|
||||||
|
:region => 'us-east-1'
|
||||||
|
)
|
||||||
|
|
||||||
|
@file = @storage.directories.new(:key => 'fognonbucket').files.new(:key => 'test.txt')
|
||||||
|
|
||||||
|
if RUBY_VERSION > '1.8.7' # ruby 1.8.x doesn't provide hash ordering
|
||||||
|
tests('#v2 url w/ response-cache-control').returns(
|
||||||
|
"https://fognonbucket.s3.amazonaws.com/test.txt?response-cache-control=No-cache&AWSAccessKeyId=123&Signature=foo&Expires=#{now.to_i + 500}"
|
||||||
|
) do
|
||||||
|
|
||||||
|
@file.url(now + 500, :query => { 'response-cache-control' => 'No-cache' })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue