From 508f4d403ea6e439a0b0f33168d0518b32f654a1 Mon Sep 17 00:00:00 2001 From: Florian Wininger Date: Wed, 13 Dec 2017 23:48:21 +0100 Subject: [PATCH] Fix #152 and 125 Signed-off-by: Florian Wininger --- api_auth.gemspec | 2 +- lib/api_auth/request_drivers/rest_client.rb | 4 +- spec/headers_spec.rb | 8 -- spec/request_drivers/rest_client_spec.rb | 102 +++++++++++++++++--- 4 files changed, 90 insertions(+), 26 deletions(-) diff --git a/api_auth.gemspec b/api_auth.gemspec index 11bfb553..a7e61591 100644 --- a/api_auth.gemspec +++ b/api_auth.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |s| s.add_development_dependency 'httpi' s.add_development_dependency 'multipart-post', '~> 2.0' s.add_development_dependency 'rake' - s.add_development_dependency 'rest-client', '~> 1.6.0' + s.add_development_dependency 'rest-client', '~> 2.0' s.add_development_dependency 'rspec', '~> 3.4' s.files = `git ls-files`.split("\n") diff --git a/lib/api_auth/request_drivers/rest_client.rb b/lib/api_auth/request_drivers/rest_client.rb index cf7870d4..e8bc81b3 100644 --- a/lib/api_auth/request_drivers/rest_client.rb +++ b/lib/api_auth/request_drivers/rest_client.rb @@ -29,13 +29,13 @@ def calculated_md5 end def populate_content_md5 - return unless %i[post put].include?(@request.method) + return unless %w[post put].include?(@request.method.to_s) @request.headers['Content-MD5'] = calculated_md5 save_headers end def md5_mismatch? - if %i[post put].include?(@request.method) + if %w[post put].include?(@request.method.to_s) calculated_md5 != content_md5 else false diff --git a/spec/headers_spec.rb b/spec/headers_spec.rb index 4fbc50b4..fe31b794 100644 --- a/spec/headers_spec.rb +++ b/spec/headers_spec.rb @@ -7,14 +7,6 @@ subject(:headers) { described_class.new(request) } let(:uri) { '' } - context 'empty uri' do - let(:uri) { ''.freeze } - - it 'adds / to canonical string' do - expect(subject.canonical_string).to eq('GET,,,/,') - end - end - context 'uri with just host without /' do let(:uri) { 'http://google.com'.freeze } diff --git a/spec/request_drivers/rest_client_spec.rb b/spec/request_drivers/rest_client_spec.rb index f7dbcf1c..7550089f 100644 --- a/spec/request_drivers/rest_client_spec.rb +++ b/spec/request_drivers/rest_client_spec.rb @@ -3,7 +3,7 @@ describe ApiAuth::RequestDrivers::RestClientRequest do let(:timestamp) { Time.now.utc.httpdate } - let(:request_path) { '/resource.xml?foo=bar&bar=foo' } + let(:request_path) { 'http://localhost/resource.xml?foo=bar&bar=foo' } let(:request_headers) do { @@ -16,7 +16,7 @@ let(:request) do RestClient::Request.new( - url: '/resource.xml?foo=bar&bar=foo', + url: 'http://localhost/resource.xml?foo=bar&bar=foo', headers: request_headers, method: :put, payload: "hello\nworld" @@ -35,7 +35,7 @@ end it 'gets the request_uri' do - expect(driven_request.request_uri).to eq('/resource.xml?foo=bar&bar=foo') + expect(driven_request.request_uri).to eq('http://localhost/resource.xml?foo=bar&bar=foo') end it 'gets the timestamp' do @@ -53,7 +53,7 @@ it 'treats no body as empty string' do request = RestClient::Request.new( - url: '/resource.xml?foo=bar&bar=foo', + url: 'http://localhost/resource.xml?foo=bar&bar=foo', headers: request_headers, method: :put ) @@ -66,7 +66,7 @@ context 'when put request' do let(:request) do RestClient::Request.new( - url: '/resource.xml?foo=bar&bar=foo', + url: 'http://localhost/resource.xml?foo=bar&bar=foo', headers: request_headers, method: :put ) @@ -80,7 +80,7 @@ context 'when get request' do let(:request) do RestClient::Request.new( - url: '/resource.xml?foo=bar&bar=foo', + url: 'http://localhost/resource.xml?foo=bar&bar=foo', headers: request_headers, method: :get ) @@ -104,7 +104,7 @@ context 'when getting' do let(:request) do RestClient::Request.new( - url: '/resource.xml?foo=bar&bar=foo', + url: 'http://localhost/resource.xml?foo=bar&bar=foo', headers: request_headers, method: :get ) @@ -119,7 +119,7 @@ context 'when posting' do let(:request) do RestClient::Request.new( - url: '/resource.xml?foo=bar&bar=foo', + url: 'http://localhost/resource.xml?foo=bar&bar=foo', headers: request_headers, method: :post, payload: "hello\nworld" @@ -140,7 +140,7 @@ context 'when putting' do let(:request) do RestClient::Request.new( - url: '/resource.xml?foo=bar&bar=foo', + url: 'http://localhost/resource.xml?foo=bar&bar=foo', headers: request_headers, method: :put, payload: "hello\nworld" @@ -161,7 +161,7 @@ context 'when deleting' do let(:request) do RestClient::Request.new( - url: '/resource.xml?foo=bar&bar=foo', + url: 'http://localhost/resource.xml?foo=bar&bar=foo', headers: request_headers, method: :delete ) @@ -203,7 +203,7 @@ context 'when getting' do let(:request) do RestClient::Request.new( - url: '/resource.xml?foo=bar&bar=foo', + url: 'http://localhost/resource.xml?foo=bar&bar=foo', headers: request_headers, method: :get ) @@ -217,7 +217,7 @@ context 'when posting' do let(:request) do RestClient::Request.new( - url: '/resource.xml?foo=bar&bar=foo', + url: 'http://localhost/resource.xml?foo=bar&bar=foo', headers: request_headers, method: :post, payload: "hello\nworld" @@ -258,7 +258,7 @@ context 'when putting' do let(:request) do RestClient::Request.new( - url: '/resource.xml?foo=bar&bar=foo', + url: 'http://localhost/resource.xml?foo=bar&bar=foo', headers: request_headers, method: :put, payload: "hello\nworld" @@ -299,7 +299,7 @@ context 'when deleting' do let(:request) do RestClient::Request.new( - url: '/resource.xml?foo=bar&bar=foo', + url: 'http://localhost/resource.xml?foo=bar&bar=foo', headers: request_headers, method: :delete ) @@ -311,12 +311,84 @@ end end + describe 'authentics?' do + context 'when getting' do + let(:request) do + RestClient::Request.new( + url: 'http://localhost/resource.xml?foo=bar&bar=foo', + method: :get + ) + end + + let(:signed_request) do + ApiAuth.sign!(request, '1044', '123') + end + + it 'validates that the signature in the request header matches the way we sign it' do + expect(ApiAuth.authentic?(signed_request, '123')).to eq true + end + end + + context 'when posting' do + let(:request) do + RestClient::Request.new( + url: 'http://localhost/resource.xml?foo=bar&bar=foo', + method: :post, + payload: "hello\nworld" + ) + end + + let(:signed_request) do + ApiAuth.sign!(request, '1044', '123') + end + + it 'validates that the signature in the request header matches the way we sign it' do + expect(ApiAuth.authentic?(signed_request, '123')).to eq true + end + end + + context 'when putting' do + let(:request) do + RestClient::Request.new( + url: 'http://localhost/resource.xml?foo=bar&bar=foo', + method: :put, + payload: "hello\nworld" + ) + end + + let(:signed_request) do + ApiAuth.sign!(request, '1044', '123') + end + + it 'validates that the signature in the request header matches the way we sign it' do + expect(ApiAuth.authentic?(signed_request, '123')).to eq true + end + end + + context 'when deleting' do + let(:request) do + RestClient::Request.new( + url: 'http://localhost/resource.xml?foo=bar&bar=foo', + method: :delete + ) + end + + let(:signed_request) do + ApiAuth.sign!(request, '1044', '123') + end + + it 'validates that the signature in the request header matches the way we sign it' do + expect(ApiAuth.authentic?(signed_request, '123')).to eq true + end + end + end + describe 'edge cases' do it "doesn't mess up symbol based headers" do headers = { 'Content-MD5' => 'e59ff97941044f85df5297e1c302d260', :content_type => 'text/plain', 'Date' => 'Mon, 23 Jan 1984 03:29:56 GMT' } - request = RestClient::Request.new(url: '/resource.xml?foo=bar&bar=foo', + request = RestClient::Request.new(url: 'http://localhost/resource.xml?foo=bar&bar=foo', headers: headers, method: :put) ApiAuth.sign!(request, 'some access id', 'some secret key')