Skip to content

Commit

Permalink
Added Request#authenticate_async
Browse files Browse the repository at this point in the history
  • Loading branch information
mloughran committed Jun 21, 2012
1 parent c1f8d5a commit 4ac3324
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 3 deletions.
9 changes: 9 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ PATH
GEM
remote: http://rubygems.org/
specs:
bacon (1.1.0)
diff-lcs (1.1.3)
em-spec (0.2.6)
bacon
eventmachine
rspec (> 2.6.0)
test-unit
eventmachine (0.12.10)
rspec (2.9.0)
rspec-core (~> 2.9.0)
rspec-expectations (~> 2.9.0)
Expand All @@ -15,10 +22,12 @@ GEM
rspec-expectations (2.9.1)
diff-lcs (~> 1.1.3)
rspec-mocks (2.9.0)
test-unit (2.4.4)

PLATFORMS
ruby

DEPENDENCIES
em-spec
rspec (~> 2.9.0)
signature!
39 changes: 39 additions & 0 deletions lib/signature.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,45 @@ def authenticate(timestamp_grace = 600)
return token
end

# Authenticate a request asynchronously
#
# This method is useful it you're running a server inside eventmachine and
# need to lookup the token asynchronously.
#
# The block is passed an auth key and a deferrable which should succeed
# with the token, or fail if the token cannot be found
#
# This method returns a deferrable which succeeds with the valid token, or
# fails with an AuthenticationError which can be used to pass the error
# back to the user
#
def authenticate_async(timestamp_grace = 600)
raise ArgumentError, "Block required" unless block_given?
df = EM::DefaultDeferrable.new

key = @auth_hash['auth_key']

unless key
df.fail(AuthenticationError.new("Missing parameter: auth_key"))
return
end

token_df = yield key
token_df.callback { |token|
begin
authenticate_by_token!(token, timestamp_grace)
df.succeed(token)
rescue AuthenticationError => e
df.fail(e)
end
}
token_df.errback {
df.fail(AuthenticationError.new("Unknown auth_key"))
}
ensure
return df
end

# Expose the authentication parameters for a signed request
#
def auth_hash
Expand Down
1 change: 1 addition & 0 deletions signature.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ Gem::Specification.new do |s|

s.add_dependency "jruby-openssl" if defined?(JRUBY_VERSION)
s.add_development_dependency "rspec", "~> 2.9.0"
s.add_development_dependency "em-spec"
end
62 changes: 62 additions & 0 deletions spec/signature_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,5 +197,67 @@
}.should raise_error(ArgumentError, "Block required")
end
end

describe "authenticate_async" do
include EM::SpecHelper
default_timeout 1

it "returns a deferrable which succeeds if authentication passes" do
request = Signature::Request.new('POST', '/some/path', @params)
em {
df = EM::DefaultDeferrable.new

request_df = request.authenticate_async do |key|
df
end

df.succeed(@token)

request_df.callback { |token|
token.should == @token
done
}
}
end

it "returns a deferrable which fails if block df fails" do
request = Signature::Request.new('POST', '/some/path', @params)
em {
df = EM::DefaultDeferrable.new

request_df = request.authenticate_async do |key|
df
end

df.fail()

request_df.errback { |e|
e.class.should == Signature::AuthenticationError
e.message.should == 'Unknown auth_key'
done
}
}
end

it "returns a deferrable which fails if request does not validate" do
request = Signature::Request.new('POST', '/some/path', @params)
em {
df = EM::DefaultDeferrable.new

request_df = request.authenticate_async do |key|
df
end

token = Signature::Token.new('key', 'wrong_secret')
df.succeed(token)

request_df.errback { |e|
e.class.should == Signature::AuthenticationError
e.message.should =~ /Invalid signature/
done
}
}
end
end
end
end
5 changes: 2 additions & 3 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
$LOAD_PATH.unshift(File.dirname(__FILE__))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))

require 'rubygems'
require 'signature'

require 'rspec'
require 'em-spec/rspec'

RSpec.configure do |config|

Expand Down

0 comments on commit 4ac3324

Please sign in to comment.