Add an Authorization middleware to generate token headers

This commit is contained in:
rick 2012-04-21 18:34:37 -06:00
parent b6410720b8
commit 52a951aed2
6 changed files with 82 additions and 35 deletions

View File

@ -1,4 +1,3 @@
require 'base64'
require 'cgi'
require 'set'
require 'forwardable'

View File

@ -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|

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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