net-http-auth-hmac 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+ gem "rake"
@@ -0,0 +1,16 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ net-http-auth-hmac (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ rake (0.9.2.2)
10
+
11
+ PLATFORMS
12
+ ruby
13
+
14
+ DEPENDENCIES
15
+ net-http-auth-hmac!
16
+ rake
@@ -0,0 +1,34 @@
1
+ # net-http-auth-hmac
2
+
3
+ ![HMAC](http://www.gmkfreelogos.com/logos/H/img/HMAC.gif)
4
+
5
+ Signs a request with given token to be validated in the backend.
6
+
7
+ ## Usage
8
+
9
+ Sending a request
10
+
11
+ ```ruby
12
+ uri = URI.parse("http://google.com/")
13
+ http = Net::HTTP.new(uri.host, uri.port)
14
+
15
+ signer = Net::HTTP::Auth::HMAC.new('super_secret_secret')
16
+ request = Net::HTTP::Post.new('/somewhere')
17
+ request.body = 'super_secret_value=42'
18
+
19
+ signed_request = signer.sign_request(request)
20
+ http.request request
21
+ ```
22
+
23
+ Receiving a request
24
+
25
+ ```ruby
26
+ signer = Net::HTTP::Auth::HMAC.new('super_secret_secret')
27
+ unsigned_request = signer.unsign_request(request)
28
+ request.body
29
+ ```
30
+
31
+ ## Installation
32
+ ```bash
33
+ gem install net-http-auth-hmac
34
+ ```
@@ -0,0 +1,12 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ task :default => [:test_units]
5
+
6
+ desc "Run basic tests"
7
+ Rake::TestTask.new("test_units") do |t|
8
+ t.pattern = 'test/*_test.rb'
9
+ t.verbose = true
10
+ t.warning = true
11
+ end
12
+
@@ -0,0 +1,64 @@
1
+ require 'openssl'
2
+ require 'net/http'
3
+ require 'base64'
4
+
5
+ class Net::HTTP
6
+ class Auth
7
+ class HMAC
8
+ def initialize(shared_secret)
9
+ @secret = shared_secret
10
+ end
11
+
12
+ def sign_request(request)
13
+ raise BodyNotFound if !request.body
14
+ request.body = base64_encode(request.body)
15
+ request['X-HMAC-Digest'] = base64_encode(signature(request.body))
16
+ request
17
+ end
18
+
19
+ def unsign_request(request)
20
+ raise DigestNotFound if !request['X-HMAC-Digest']
21
+ request_signature = base64_decode(request['X-HMAC-Digest'])
22
+ raise InvalidSignature if request_signature != signature(request.body)
23
+
24
+ request.body = base64_decode(request.body)
25
+ request
26
+ end
27
+
28
+ private
29
+
30
+ def signature(payload)
31
+ OpenSSL::HMAC.digest('sha256', @secret, payload)
32
+ end
33
+
34
+ def base64_encode(string)
35
+ Base64.urlsafe_encode64(string)
36
+ end
37
+
38
+ def base64_decode(string)
39
+ Base64.urlsafe_decode64(string)
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+
46
+ class Net::HTTP::Auth::HMAC
47
+ class InvalidSignature < StandardError
48
+ def message
49
+ "The X-HMAC-Digest it's invalid"
50
+ end
51
+ end
52
+
53
+ class BodyNotFound < StandardError
54
+ def message
55
+ "The body of the request it's missing"
56
+ end
57
+ end
58
+
59
+ class DigestNotFound < StandardError
60
+ def message
61
+ "The X-HMAC-Digest it's missing"
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,11 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "net-http-auth-hmac"
3
+ s.version = "0.0.1"
4
+ s.summary = "HMAC base identity authentication"
5
+ s.description = "Exchanges a digest to be validated against a token"
6
+ s.authors = ["elcuervo"]
7
+ s.email = ["yo@brunoaguirre.com"]
8
+ s.homepage = "http://github.com/elcuervo/net-http-auth-hmac"
9
+ s.files = `git ls-files`.split("\n")
10
+ s.test_files = `git ls-files test`.split("\n")
11
+ end
@@ -0,0 +1,57 @@
1
+ $: << File.join(File.dirname(__FILE__), '../lib')
2
+ require 'test/unit'
3
+ require 'net/http'
4
+ require 'net/http/auth/hmac'
5
+
6
+ class TestNetHTTPAuthHMAC < Test::Unit::TestCase
7
+ def setup
8
+ @body = 'Once upon a midnight dreary, while I pondered weak and weary'
9
+ @request = Net::HTTP::Post.new('/signed')
10
+ @request.body = @body
11
+ end
12
+
13
+ def test_sending_and_unsigning_a_request
14
+ secret = 'changeme'
15
+ signer = Net::HTTP::Auth::HMAC.new(secret)
16
+ signed_request = signer.sign_request(@request)
17
+
18
+ assert signed_request.is_a?(Net::HTTP::Post)
19
+ assert signed_request['X-HMAC-Digest']
20
+ assert signed_request.body != @body
21
+
22
+ unsigned_request = signer.unsign_request(signed_request)
23
+ assert_equal unsigned_request.body, @body
24
+ end
25
+
26
+ def test_raising_an_error_when_the_header_is_missing
27
+ signer = Net::HTTP::Auth::HMAC.new('one')
28
+ request = Net::HTTP::Post.new('/somewhere')
29
+ request.body = 'something'
30
+
31
+ assert_raise Net::HTTP::Auth::HMAC::DigestNotFound do
32
+ signer.unsign_request(request)
33
+ end
34
+ end
35
+
36
+ def test_raising_an_error_when_the_body_is_missing
37
+ signer = Net::HTTP::Auth::HMAC.new('one')
38
+ request = Net::HTTP::Post.new('/somewhere')
39
+
40
+ assert_raise Net::HTTP::Auth::HMAC::BodyNotFound do
41
+ signer.sign_request(request)
42
+ end
43
+ end
44
+
45
+ def test_raising_an_error_when_the_signature_is_invalid
46
+ one = Base64.urlsafe_encode64('one')
47
+ two = Base64.urlsafe_encode64('two')
48
+
49
+ signer = Net::HTTP::Auth::HMAC.new(one)
50
+ signed_request = signer.sign_request(@request)
51
+ signed_request['X-HMAC-Digest'] = two
52
+
53
+ assert_raise Net::HTTP::Auth::HMAC::InvalidSignature do
54
+ signer.unsign_request(signed_request)
55
+ end
56
+ end
57
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: net-http-auth-hmac
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - elcuervo
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-14 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Exchanges a digest to be validated against a token
15
+ email:
16
+ - yo@brunoaguirre.com
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - Gemfile
22
+ - Gemfile.lock
23
+ - README.md
24
+ - Rakefile
25
+ - lib/net/http/auth/hmac.rb
26
+ - net-http-auth-hmac.gemspec
27
+ - test/net-http-auth-hmac_test.rb
28
+ homepage: http://github.com/elcuervo/net-http-auth-hmac
29
+ licenses: []
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubyforge_project:
48
+ rubygems_version: 1.8.22
49
+ signing_key:
50
+ specification_version: 3
51
+ summary: HMAC base identity authentication
52
+ test_files:
53
+ - test/net-http-auth-hmac_test.rb