From d0df9abfb0e79d4631b3a9ba56b229ae718ac6aa Mon Sep 17 00:00:00 2001 From: rick Date: Wed, 28 Dec 2011 15:03:40 -0700 Subject: [PATCH] merrrrrge --- lib/faraday/connection.rb | 20 ++++----- lib/faraday/request.rb | 8 +++- lib/faraday/request/basic_authentication.rb | 17 ++++++++ lib/faraday/request/token_authentication.rb | 21 +++++++++ test/authentication_middleware_test.rb | 48 +++++++++++++++++++++ test/connection_test.rb | 31 ++++--------- 6 files changed, 108 insertions(+), 37 deletions(-) create mode 100644 lib/faraday/request/basic_authentication.rb create mode 100644 lib/faraday/request/token_authentication.rb create mode 100644 test/authentication_middleware_test.rb diff --git a/lib/faraday/connection.rb b/lib/faraday/connection.rb index 7b1bf1d2..9f3463b9 100644 --- a/lib/faraday/connection.rb +++ b/lib/faraday/connection.rb @@ -31,8 +31,6 @@ module Faraday @ssl = options[:ssl] || {} @parallel_manager = options[:parallel] - self.url_prefix = url if url - proxy(options.fetch(:proxy) { ENV['http_proxy'] }) @params.update options[:params] if options[:params] @@ -43,6 +41,12 @@ module Faraday else @builder = options[:builder] || Builder.new end + + self.url_prefix = url if url + proxy(options[:proxy]) + + @params.update options[:params] if options[:params] + @headers.update options[:headers] if options[:headers] end def use(klass, *args, &block) @@ -115,19 +119,11 @@ module Faraday end def basic_auth(login, pass) - auth = Base64.encode64("#{login}:#{pass}") - auth.gsub!("\n", "") - @headers['authorization'] = "Basic #{auth}" + @builder.insert(0, Faraday::Request::BasicAuthentication, login, pass) end def token_auth(token, options = {}) - values = ["token=#{token.to_s.inspect}"] - options.each do |key, value| - values << "#{key}=#{value.to_s.inspect}" - end - # 21 = "Authorization: Token ".size - comma = ",\n#{' ' * 21}" - @headers['authorization'] = "Token #{values * comma}" + @builder.insert(0, Faraday::Request::TokenAuthentication, token, options) end def in_parallel? diff --git a/lib/faraday/request.rb b/lib/faraday/request.rb index 0a48fb14..5de282cd 100644 --- a/lib/faraday/request.rb +++ b/lib/faraday/request.rb @@ -17,13 +17,17 @@ module Faraday :UrlEncoded => 'url_encoded', :Multipart => 'multipart', :Retry => 'retry', - :Timeout => 'timeout' + :Timeout => 'timeout', + :BasicAuthentication => 'basic_authentication', + :TokenAuthentication => 'token_authentication' register_lookup_modules \ :json => :JSON, :url_encoded => :UrlEncoded, :multipart => :Multipart, - :retry => :Retry + :retry => :Retry, + :basic_authentication => :BasicAuthentication, + :token_authentication => :TokenAuthentication attr_reader :method diff --git a/lib/faraday/request/basic_authentication.rb b/lib/faraday/request/basic_authentication.rb new file mode 100644 index 00000000..6059deeb --- /dev/null +++ b/lib/faraday/request/basic_authentication.rb @@ -0,0 +1,17 @@ +require 'base64' + +module Faraday + class Request::BasicAuthentication < Faraday::Middleware + def initialize(app, login, pass) + super(app) + @header_value = "Basic #{Base64.encode64([login, pass].join(':')).gsub("\n", '')}" + end + + def call(env) + unless env[:request_headers]['Authorization'] + env[:request_headers]['Authorization'] = @header_value + end + @app.call(env) + end + end +end diff --git a/lib/faraday/request/token_authentication.rb b/lib/faraday/request/token_authentication.rb new file mode 100644 index 00000000..c3579a33 --- /dev/null +++ b/lib/faraday/request/token_authentication.rb @@ -0,0 +1,21 @@ +module Faraday + class Request::TokenAuthentication < Faraday::Middleware + def initialize(app, token, options={}) + super(app) + + values = ["token=#{token.to_s.inspect}"] + options.each do |key, value| + values << "#{key}=#{value.to_s.inspect}" + end + comma = ",\n#{' ' * ('Authorization: Token '.size)}" + @header_value = "Token #{values * comma}" + end + + def call(env) + unless env[:request_headers]['Authorization'] + env[:request_headers]['Authorization'] = @header_value + end + @app.call(env) + end + end +end diff --git a/test/authentication_middleware_test.rb b/test/authentication_middleware_test.rb new file mode 100644 index 00000000..ce868c8f --- /dev/null +++ b/test/authentication_middleware_test.rb @@ -0,0 +1,48 @@ +require File.expand_path(File.join(File.dirname(__FILE__), 'helper')) + +class AuthenticationMiddlewareTest < Faraday::TestCase + def conn + Faraday::Connection.new('http://example.net/') do |builder| + yield builder + builder.adapter :test do |stub| + stub.get('/auth-echo') do |env| + [200, {}, env[:request_headers]['Authorization']] + end + end + end + end + + def test_basic_middleware_adds_basic_header + response = conn { |b| b.request :basic_authentication, 'aladdin', 'opensesame' }.get('/auth-echo') + assert_equal 'Basic YWxhZGRpbjpvcGVuc2VzYW1l', response.body + end + + def test_basic_middleware_adds_basic_header_correctly_with_long_values + response = conn { |b| b.request :basic_authentication, 'A' * 255, '' }.get('/auth-echo') + assert_equal "Basic #{'QUFB' * 85}Og==", response.body + end + + def test_basic_middleware_does_not_interfere_with_existing_authorization + response = conn { |b| b.request :basic_authentication, 'aladdin', 'opensesame' }. + get('/auth-echo', :authorization => 'Token token="bar"') + assert_equal 'Token token="bar"', response.body + end + + def test_token_middleware_adds_token_header + response = conn { |b| b.request :token_authentication, 'quux' }.get('/auth-echo') + assert_equal 'Token token="quux"', response.body + end + + def test_token_middleware_includes_other_values_if_provided + response = conn { |b| + b.request :token_authentication, 'baz', :foo => 42 + }.get('/auth-echo') + assert_equal "Token token=\"baz\",\n foo=\"42\"", response.body + end + + def test_token_middleware_does_not_interfere_with_existing_authorization + response = conn { |b| b.request :token_authentication, 'quux' }. + get('/auth-echo', :authorization => 'Token token="bar"') + assert_equal 'Token token="bar"', response.body + end +end diff --git a/test/connection_test.rb b/test/connection_test.rb index 474314a0..1e38baf4 100644 --- a/test/connection_test.rb +++ b/test/connection_test.rb @@ -67,39 +67,24 @@ class TestConnection < Faraday::TestCase assert_equal 'Faraday', conn.headers['User-agent'] end - def test_basic_auth_sets_authorization_header + def test_basic_auth_prepends_basic_auth_middleware conn = Faraday::Connection.new conn.basic_auth 'Aladdin', 'open sesame' - assert_equal 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==', conn.headers['Authorization'] - end - - def test_long_basic_auth_sets_authorization_header_without_new_lines - conn = Faraday::Connection.new - conn.basic_auth "A" * 255, "" - assert_equal "Basic #{'QUFB' * 85}Og==", conn.headers['Authorization'] - end - - def test_auto_parses_basic_auth_from_url - conn = Faraday::Connection.new :url => "http://aladdin:opensesame@sushi.com/fish" - assert_equal 'Basic YWxhZGRpbjpvcGVuc2VzYW1l', conn.headers['Authorization'] + assert_equal Faraday::Request::BasicAuthentication, conn.builder[0].klass + assert_equal ['Aladdin', 'open sesame'], conn.builder[0].instance_eval { @args } end def test_auto_parses_basic_auth_from_url_and_unescapes conn = Faraday::Connection.new :url => "http://foo%40bar.com:pass%20word@sushi.com/fish" - assert_equal 'Basic Zm9vQGJhci5jb206cGFzcyB3b3Jk', conn.headers['Authorization'] + assert_equal Faraday::Request::BasicAuthentication, conn.builder[0].klass + assert_equal ['foo@bar.com', 'pass word'], conn.builder[0].instance_eval { @args } end - def test_token_auth_sets_authorization_header - conn = Faraday::Connection.new - conn.token_auth 'abcdef' - assert_equal 'Token token="abcdef"', conn.headers['Authorization'] - end - - def test_token_auth_with_options_sets_authorization_header + def test_token_auth_prepends_token_auth_middleware conn = Faraday::Connection.new conn.token_auth 'abcdef', :nonce => 'abc' - assert_equal 'Token token="abcdef", - nonce="abc"', conn.headers['Authorization'] + assert_equal Faraday::Request::TokenAuthentication, conn.builder[0].klass + assert_equal ['abcdef', { :nonce => 'abc' }], conn.builder[0].instance_eval { @args } end def test_build_url_uses_connection_host_as_default_uri_host