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 'cgi'
require 'set' require 'set'
require 'forwardable' require 'forwardable'

View File

@ -15,18 +15,20 @@ module Faraday
autoload_all 'faraday/request', autoload_all 'faraday/request',
:UrlEncoded => 'url_encoded', :UrlEncoded => 'url_encoded',
:Multipart => 'multipart', :Multipart => 'multipart',
:Retry => 'retry', :Retry => 'retry',
:Timeout => 'timeout', :Timeout => 'timeout',
:Authorization => 'authorization',
:BasicAuthentication => 'basic_authentication', :BasicAuthentication => 'basic_authentication',
:TokenAuthentication => 'token_authentication' :TokenAuthentication => 'token_authentication'
register_middleware \ register_middleware \
:url_encoded => :UrlEncoded, :url_encoded => :UrlEncoded,
:multipart => :Multipart, :multipart => :Multipart,
:retry => :Retry, :retry => :Retry,
:basic_auth => :BasicAuthentication, :authorization => :Authorization,
:token_auth => :TokenAuthentication :basic_auth => :BasicAuthentication,
:token_auth => :TokenAuthentication
def self.create(request_method) def self.create(request_method)
new(request_method).tap do |request| 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' require 'base64'
module Faraday module Faraday
class Request::BasicAuthentication < Faraday::Middleware class Request::BasicAuthentication < Request::Authorization
def initialize(app, login, pass) def self.build(login, pass)
super(app) value = Base64.encode64([login, pass].join(':'))
@header_value = "Basic #{Base64.encode64([login, pass].join(':')).gsub("\n", '')}" value.gsub!("\n", '')
end super(:Basic, value)
def call(env)
unless env[:request_headers]['Authorization']
env[:request_headers]['Authorization'] = @header_value
end
@app.call(env)
end end
end end
end end

View File

@ -1,21 +1,15 @@
module Faraday module Faraday
class Request::TokenAuthentication < Faraday::Middleware class Request::TokenAuthentication < Request::Authorization
def initialize(app, token, options={}) # Public
super(app) def self.build(token, options = nil)
options ||= {}
values = ["token=#{token.to_s.inspect}"] options[:token] = token
options.each do |key, value| super :Token, options
values << "#{key}=#{value.to_s.inspect}"
end
comma = ",\n#{' ' * ('Authorization: Token '.size)}"
@header_value = "Token #{values * comma}"
end end
def call(env) def initialize(app, token, options = nil)
unless env[:request_headers]['Authorization'] super(app, token, options)
env[:request_headers]['Authorization'] = @header_value
end
@app.call(env)
end end
end end
end end

View File

@ -37,7 +37,9 @@ class AuthenticationMiddlewareTest < Faraday::TestCase
response = conn { |b| response = conn { |b|
b.request :token_auth, 'baz', :foo => 42 b.request :token_auth, 'baz', :foo => 42
}.get('/auth-echo') }.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 end
def test_token_middleware_does_not_interfere_with_existing_authorization 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"') get('/auth-echo', nil, :authorization => 'Token token="bar"')
assert_equal 'Token token="bar"', response.body assert_equal 'Token token="bar"', response.body
end 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 end