diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..69b1fe0 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,11 @@ +language: ruby +rvm: + - 1.8.7 + - 1.9.2 + - 1.9.3 + - jruby-18mode # JRuby in 1.8 mode + - jruby-19mode # JRuby in 1.9 mode + - rbx-18mode + - rbx-19mode + +script: bundle exec rspec spec diff --git a/Gemfile.lock b/Gemfile.lock index 1d6c8dd..42ab508 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,28 +2,23 @@ PATH remote: . specs: signature (0.1.2) - ruby-hmac GEM remote: http://rubygems.org/ specs: - diff-lcs (1.1.2) - rspec (2.0.1) - rspec-core (~> 2.0.1) - rspec-expectations (~> 2.0.1) - rspec-mocks (~> 2.0.1) - rspec-core (2.0.1) - rspec-expectations (2.0.1) - diff-lcs (>= 1.1.2) - rspec-mocks (2.0.1) - rspec-core (~> 2.0.1) - rspec-expectations (~> 2.0.1) - ruby-hmac (0.4.0) + diff-lcs (1.1.3) + rspec (2.9.0) + rspec-core (~> 2.9.0) + rspec-expectations (~> 2.9.0) + rspec-mocks (~> 2.9.0) + rspec-core (2.9.0) + rspec-expectations (2.9.1) + diff-lcs (~> 1.1.3) + rspec-mocks (2.9.0) PLATFORMS ruby DEPENDENCIES - rspec (~> 2.0.0) - ruby-hmac + rspec (~> 2.9.0) signature! diff --git a/README.md b/README.md index 50e285a..49acf21 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,70 @@ signature ========= +[![Build Status](https://secure.travis-ci.org/markburns/signature.png?branch=master)](http://travis-ci.org/markburns/signature) + Examples -------- Client example - params = {:some => 'parameters'} - token = Signature::Token.new('my_key', 'my_secret') - request = Signature::Request.new('POST', '/api/thing', params) - auth_hash = request.sign(token) - query_params = params.merge(auth_hash) - - HTTParty.post('http://myservice/api/thing', { - :query => query_params - }) +```ruby +params = {:some => 'parameters'} +token = Signature::Token.new('my_key', 'my_secret') +request = Signature::Request.new('POST', '/api/thing', params) +auth_hash = request.sign(token) +query_params = params.merge(auth_hash) + +HTTParty.post('http://myservice/api/thing', { + :query => query_params +}) +``` `query_params` looks like: - { - :some => "parameters", - :auth_timestamp => 1273231888, - :auth_signature => "28b6bb0f242f71064916fad6ae463fe91f5adc302222dfc02c348ae1941eaf80", - :auth_version => "1.0", - :auth_key => "my_key" - } +```ruby +{ + :some => "parameters", + :auth_timestamp => 1273231888, + :auth_signature => "28b6bb0f242f71064916fad6ae463fe91f5adc302222dfc02c348ae1941eaf80", + :auth_version => "1.0", + :auth_key => "my_key" +} +``` Server example (sinatra) - error Signature::AuthenticationError do |controller| - error = controller.env["sinatra.error"] - halt 401, "401 UNAUTHORIZED: #{error.message}\n" - end +```ruby +error Signature::AuthenticationError do |controller| + error = controller.env["sinatra.error"] + halt 401, "401 UNAUTHORIZED: #{error.message}\n" +end + +post '/api/thing' do + request = Signature::Request.new('POST', env["REQUEST_PATH"], params) + # This will raise a Signature::AuthenticationError if request does not authenticate + token = request.authenticate do |key| + Signature::Token.new(key, lookup_secret(key)) + end + + # Do whatever you need to do +end +``` + +Pre-requisites +------------ +Tested against these Ruby versions + * 1.8.7 + * 1.9.2 + * 1.9.3 + * rbx-18mode + * rbx-19mode - post '/api/thing' do - request = Signature::Request.new('POST', env["REQUEST_PATH"], params) - # This will raise a Signature::AuthenticationError if request does not authenticate - token = request.authenticate do |key| - Signature::Token.new(key, lookup_secret(key)) - end +However JRuby currently fails with +java.security.NoSuchAlgorithmException: sha256 MessageDigest not available + * jruby-18mode # JRuby in 1.8 mode + * jruby-19mode # JRuby in 1.9 mode - # Do whatever you need to do - end Developing ---------- diff --git a/lib/signature.rb b/lib/signature.rb index ea62ba1..319aafc 100644 --- a/lib/signature.rb +++ b/lib/signature.rb @@ -1,4 +1,4 @@ -require 'hmac-sha2' +require 'openssl' module Signature class AuthenticationError < RuntimeError; end @@ -90,7 +90,11 @@ def auth_hash private def signature(token) - HMAC::SHA256.hexdigest(token.secret, string_to_sign) + OpenSSL::HMAC.hexdigest(digest, token.secret, string_to_sign) + end + + def digest + OpenSSL::Digest::Digest.new('sha256') end def string_to_sign diff --git a/signature.gemspec b/signature.gemspec index accf999..1f757da 100644 --- a/signature.gemspec +++ b/signature.gemspec @@ -17,6 +17,6 @@ Gem::Specification.new do |s| s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.require_paths = ["lib"] - s.add_dependency "ruby-hmac" - s.add_development_dependency "rspec", "~> 2.0.0" + s.add_dependency "jruby-openssl" if defined?(JRUBY_VERSION) + s.add_development_dependency "rspec", "~> 2.9.0" end