Skip to content

Commit

Permalink
Forward the Hmac digest method in the Header HMAC_METHOD
Browse files Browse the repository at this point in the history
  • Loading branch information
fwininger committed Feb 22, 2016
1 parent 188e6d0 commit f13f5f7
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 11 deletions.
17 changes: 11 additions & 6 deletions lib/api_auth/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class << self
#
# secret_key: assigned secret key that is known to both parties
def sign!(request, access_id, secret_key, options = {})
options = { :override_http_method => nil, :with_http_method => false, :digest => 'sha1' }.merge(options)
options = { :override_http_method => nil, :with_http_method => false, :digest => 'SHA1' }.merge(options)
headers = Headers.new(request)
headers.calculate_md5
headers.set_date
Expand All @@ -32,9 +32,11 @@ def sign!(request, access_id, secret_key, options = {})
# secret key. Returns true if the request is authentic and false otherwise.
def authentic?(request, secret_key, options = {})
return false if secret_key.nil?
options = { :override_http_method => nil, :digest => 'sha1' }.merge(options)

options = { :override_http_method => nil }.merge(options)

headers = Headers.new(request)

if headers.md5_mismatch?
false
elsif !signatures_match?(headers, secret_key, options)
Expand All @@ -50,7 +52,7 @@ def authentic?(request, secret_key, options = {})
def access_id(request)
headers = Headers.new(request)
if match_data = parse_auth_header(headers.authorization_header)
return match_data[1]
return match_data[2]
end

nil
Expand All @@ -67,7 +69,7 @@ def generate_secret_key

private

AUTH_HEADER_PATTERN = /APIAuth ([^:]+):(.+)$/
AUTH_HEADER_PATTERN = /APIAuth(?:-HMAC-(MD[245]|SHA(?:1|224|256|384|512)*))? ([^:]+):(.+)$/

def request_too_old?(headers)
# 900 seconds is 15 minutes
Expand All @@ -81,7 +83,10 @@ def signatures_match?(headers, secret_key, options)
match_data = parse_auth_header(headers.authorization_header)
return false unless match_data

header_sig = match_data[2]
digest = match_data[1].blank? ? 'SHA1' : match_data[1].upcase
options = { :digest => digest }.merge(options)

header_sig = match_data[3]
calculated_sig_no_http = hmac_signature(headers, secret_key, options.merge(:with_http_method => false))
calculated_sig_with_http = hmac_signature(headers, secret_key, options.merge(:with_http_method => true))

Expand All @@ -99,7 +104,7 @@ def hmac_signature(headers, secret_key, options)
end

def auth_header(headers, access_id, secret_key, options)
"APIAuth #{access_id}:#{hmac_signature(headers, secret_key, options)}"
"APIAuth-HMAC-#{options[:digest].upcase} #{access_id}:#{hmac_signature(headers, secret_key, options)}"
end

def parse_auth_header(auth_header)
Expand Down
6 changes: 3 additions & 3 deletions spec/api_auth_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def hmac(secret_key, request, canonical_string = nil, digest = 'sha1')
it 'calculates the hmac_signature as expected' do
ApiAuth.sign!(request, '1044', '123')
signature = hmac('123', request)
expect(request.headers['Authorization']).to eq("APIAuth 1044:#{signature}")
expect(request.headers['Authorization']).to eq("APIAuth-HMAC-SHA1 1044:#{signature}")
end

context 'when passed the with_http_method option' do
Expand All @@ -69,7 +69,7 @@ def hmac(secret_key, request, canonical_string = nil, digest = 'sha1')
it 'calculates the hmac_signature with http method' do
ApiAuth.sign!(request, '1044', '123', :with_http_method => true)
signature = hmac('123', request, canonical_string)
expect(request['Authorization']).to eq("APIAuth 1044:#{signature}")
expect(request['Authorization']).to eq("APIAuth-HMAC-SHA1 1044:#{signature}")
end
end

Expand All @@ -87,7 +87,7 @@ def hmac(secret_key, request, canonical_string = nil, digest = 'sha1')
it 'calculates the hmac_signature with http method' do
ApiAuth.sign!(request, '1044', '123', :with_http_method => true, :digest => 'sha256')
signature = hmac('123', request, canonical_string, 'sha256')
expect(request['Authorization']).to eq("APIAuth 1044:#{signature}")
expect(request['Authorization']).to eq("APIAuth-HMAC-SHA256 1044:#{signature}")
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions spec/railtie_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class TestResource < ActiveResource::Base
ActiveResource::HttpMock.respond_to do |mock|
mock.get '/test_resources/1.xml',
{
'Authorization' => 'APIAuth 1044:IbTx7VzSOGU55HNbV4y2jZDnVis=',
'Authorization' => 'APIAuth-HMAC-SHA1 1044:IbTx7VzSOGU55HNbV4y2jZDnVis=',
'Accept' => 'application/xml',
'DATE' => 'Mon, 23 Jan 1984 03:29:56 GMT'
},
Expand All @@ -139,7 +139,7 @@ class TestResourceForHttpMethod < ActiveResource::Base
ActiveResource::HttpMock.respond_to do |mock|
mock.get '/test_resource_for_http_methods/1.xml',
{
'Authorization' => 'APIAuth 1044:Gq190cxgKm7oWH1fc+y8+wmD9ts=',
'Authorization' => 'APIAuth-HMAC-SHA1 1044:Gq190cxgKm7oWH1fc+y8+wmD9ts=',
'Accept' => 'application/xml',
'DATE' => 'Mon, 23 Jan 1984 03:29:56 GMT'
},
Expand Down

0 comments on commit f13f5f7

Please sign in to comment.