From 52a951aed2fc03fb6f2e2cb0293e4d7ba39e6db2 Mon Sep 17 00:00:00 2001 From: rick Date: Sat, 21 Apr 2012 18:34:37 -0600 Subject: [PATCH] Add an Authorization middleware to generate token headers --- lib/faraday/connection.rb | 1 - lib/faraday/request.rb | 16 +++++---- lib/faraday/request/authorization.rb | 40 +++++++++++++++++++++ lib/faraday/request/basic_authentication.rb | 17 ++++----- lib/faraday/request/token_authentication.rb | 24 +++++-------- test/authentication_middleware_test.rb | 19 +++++++++- 6 files changed, 82 insertions(+), 35 deletions(-) create mode 100644 lib/faraday/request/authorization.rb diff --git a/lib/faraday/connection.rb b/lib/faraday/connection.rb index c047d551..f5506ad3 100644 --- a/lib/faraday/connection.rb +++ b/lib/faraday/connection.rb @@ -1,4 +1,3 @@ -require 'base64' require 'cgi' require 'set' require 'forwardable' diff --git a/lib/faraday/request.rb b/lib/faraday/request.rb index c590b16f..53993cd3 100644 --- a/lib/faraday/request.rb +++ b/lib/faraday/request.rb @@ -15,18 +15,20 @@ module Faraday autoload_all 'faraday/request', :UrlEncoded => 'url_encoded', - :Multipart => 'multipart', - :Retry => 'retry', - :Timeout => 'timeout', + :Multipart => 'multipart', + :Retry => 'retry', + :Timeout => 'timeout', + :Authorization => 'authorization', :BasicAuthentication => 'basic_authentication', :TokenAuthentication => 'token_authentication' register_middleware \ :url_encoded => :UrlEncoded, - :multipart => :Multipart, - :retry => :Retry, - :basic_auth => :BasicAuthentication, - :token_auth => :TokenAuthentication + :multipart => :Multipart, + :retry => :Retry, + :authorization => :Authorization, + :basic_auth => :BasicAuthentication, + :token_auth => :TokenAuthentication def self.create(request_method) new(request_method).tap do |request| diff --git a/lib/faraday/request/authorization.rb b/lib/faraday/request/authorization.rb new file mode 100644 index 00000000..1ec3315f --- /dev/null +++ b/lib/faraday/request/authorization.rb @@ -0,0 +1,40 @@ +module Faraday + class Request::Authorization < Faraday::Middleware + HEADER_KEY = "Authorization".freeze + + # Public + def self.build(type, token) + case token + when String, Symbol then "#{type} #{token}" + when Hash then build_hash(type.to_s, token) + else + raise ArgumentError, "Can't build an Authorization #{type} header from #{token.inspect}" + end + end + + # Internal + def self.build_hash(type, hash) + offset = HEADER_KEY.size + type.size + 3 + comma = ",\n#{' ' * offset}" + values = [] + hash.each do |key, value| + values << "#{key}=#{value.to_s.inspect}" + end + "#{type} #{values * comma}" + end + + def initialize(app, type, token) + @header_value = self.class.build(type, token) + super(app) + end + + # Public + def call(env) + unless env[:request_headers][HEADER_KEY] + env[:request_headers][HEADER_KEY] = @header_value + end + @app.call(env) + end + end +end + diff --git a/lib/faraday/request/basic_authentication.rb b/lib/faraday/request/basic_authentication.rb index 6059deeb..d02f1f62 100644 --- a/lib/faraday/request/basic_authentication.rb +++ b/lib/faraday/request/basic_authentication.rb @@ -1,17 +1,12 @@ 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) + class Request::BasicAuthentication < Request::Authorization + def self.build(login, pass) + value = Base64.encode64([login, pass].join(':')) + value.gsub!("\n", '') + super(:Basic, value) end end end + diff --git a/lib/faraday/request/token_authentication.rb b/lib/faraday/request/token_authentication.rb index c3579a33..ce6e2fe1 100644 --- a/lib/faraday/request/token_authentication.rb +++ b/lib/faraday/request/token_authentication.rb @@ -1,21 +1,15 @@ 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}" + class Request::TokenAuthentication < Request::Authorization + # Public + def self.build(token, options = nil) + options ||= {} + options[:token] = token + super :Token, options end - def call(env) - unless env[:request_headers]['Authorization'] - env[:request_headers]['Authorization'] = @header_value - end - @app.call(env) + def initialize(app, token, options = nil) + super(app, token, options) end end end + diff --git a/test/authentication_middleware_test.rb b/test/authentication_middleware_test.rb index 5396c7f7..4b20107e 100644 --- a/test/authentication_middleware_test.rb +++ b/test/authentication_middleware_test.rb @@ -37,7 +37,9 @@ class AuthenticationMiddlewareTest < Faraday::TestCase response = conn { |b| b.request :token_auth, 'baz', :foo => 42 }.get('/auth-echo') - assert_equal "Token token=\"baz\",\n foo=\"42\"", response.body + assert_match /^Token /, response.body + assert_match /token="baz"/, response.body + assert_match /foo="42"/, response.body end def test_token_middleware_does_not_interfere_with_existing_authorization @@ -45,4 +47,19 @@ class AuthenticationMiddlewareTest < Faraday::TestCase get('/auth-echo', nil, :authorization => 'Token token="bar"') assert_equal 'Token token="bar"', response.body end + + def test_authorization_middleware_with_string + response = conn { |b| + b.request :authorization, 'custom', 'abc def' + }.get('/auth-echo') + assert_match /^custom abc def$/, response.body + end + + def test_authorization_middleware_with_hash + response = conn { |b| + b.request :authorization, 'baz', :foo => 42 + }.get('/auth-echo') + assert_match /^baz /, response.body + assert_match /foo="42"/, response.body + end end