rack-jwt 0.1.0 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e20bf24155aaeda649c643bde660ed334b5e081d
4
- data.tar.gz: 125bff003cd0fc9f3d2ec2feb7fd7d1fa01438bc
3
+ metadata.gz: 2cdc1b0bd5715e4d4d5e8cd04822d0e6825b089f
4
+ data.tar.gz: 2397aac243a1d587e109f46942cecdaaccb9b5cd
5
5
  SHA512:
6
- metadata.gz: 8ebece61f89d84ae0b61e82a3631a556a09597bbc2e6265eb9beacc6ef958859ceb2f7ab6bcdabf407ee36e97160396ce7db80da7791d611860329560f5c77b7
7
- data.tar.gz: 85107621925d5e21c2a8d7d275b429622155a596a49cad78520dcb93f80ba7104ac6e84f4a627095fbb685f74eee28680fc242f7ed91c883c76faa937a69d7b5
6
+ metadata.gz: 1ccae31dc0d69b94d0da8243276c532b2793dbae1563da3b328a163d9f03f5284abb58f60a193b8e421591ca9f9ff0e2b1b6bac9dcd80a0954525b6ffd25d371
7
+ data.tar.gz: 03b28fa23d5d00bce804435ff76c6e1dd4f873f6c5d49bf8830ee5295ad747d90e5dbfba7fcb371d34f58968534fb7725e1545272ec82a48f78b582808f62019
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.0.0
4
+ - 2.2.0
data/README.md CHANGED
@@ -1,4 +1,8 @@
1
- # Rack::Jwt
1
+ # Rack::JWT
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/rack-jwt.svg)](http://badge.fury.io/rb/rack-jwt)
4
+ [![Build Status](https://travis-ci.org/eigenbart/rack-jwt.svg)](https://travis-ci.org/eigenbart/rack-jwt)
5
+ [![Code Climate](https://codeclimate.com/github/eigenbart/rack-jwt/badges/gpa.svg)](https://codeclimate.com/github/eigenbart/rack-jwt)
2
6
 
3
7
  This gem provides JSON Web Token (JWT) based authentication.
4
8
 
data/Rakefile CHANGED
@@ -1,2 +1,9 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
2
3
 
4
+ desc "Run RSpec"
5
+ RSpec::Core::RakeTask.new do |t|
6
+ t.verbose = false
7
+ end
8
+
9
+ task :default => :spec
data/lib/rack/jwt/auth.rb CHANGED
@@ -10,57 +10,49 @@ module Rack
10
10
  end
11
11
 
12
12
  def call(env)
13
- if @exclude.include? env["PATH_INFO"]
13
+ if @exclude.include? env['PATH_INFO']
14
14
  @app.call(env)
15
- elsif env["HTTP_AUTHORIZATION"]
16
- begin
17
- if env["HTTP_AUTHORIZATION"].split(" ").first != 'Bearer'
18
- invalid_auth_header
19
- else
20
- token = env["HTTP_AUTHORIZATION"].split(" ")[-1]
21
- decoded_token = Token.decode(token, @secret)
22
- env["jwt.header"] = decoded_token.last
23
- env["jwt.payload"] = decoded_token.first
24
- @app.call(env)
25
- end
26
- rescue
27
- unauthorized
28
- end
29
15
  else
30
- no_auth_header
16
+ check_jwt_token(env)
31
17
  end
32
18
  end
33
19
 
34
20
  private
35
21
 
36
- def unauthorized
37
- body = { error: "Invalid JWT token" }.to_json
38
- headers = {
39
- 'Content-Type' => 'application/json',
40
- 'Content-Length' => body.bytesize.to_s
41
- }
42
-
43
- return [401, headers, [body]]
22
+ def check_jwt_token(env)
23
+ if valid_header?(env)
24
+ begin
25
+ token = env['HTTP_AUTHORIZATION'].split(' ')[-1]
26
+ decoded_token = Token.decode(token, @secret)
27
+ env['jwt.header'] = decoded_token.last
28
+ env['jwt.payload'] = decoded_token.first
29
+ @app.call(env)
30
+ rescue
31
+ return_error('Invalid JWT token')
32
+ end
33
+ else
34
+ return_jwt_header_error(env)
35
+ end
44
36
  end
45
37
 
46
- def no_auth_header
47
- body = { error: "Missing Authorization header" }.to_json
48
- headers = {
49
- 'Content-Type' => 'application/json',
50
- 'Content-Length' => body.bytesize.to_s
51
- }
38
+ def return_jwt_header_error(env)
39
+ if env['HTTP_AUTHORIZATION'].nil?
40
+ return_error('Missing Authorization header')
41
+ elsif env['HTTP_AUTHORIZATION'].split(' ').first != 'Bearer'
42
+ return_error('Invalid Authorization header format')
43
+ end
44
+ end
52
45
 
53
- return [401, headers, [body]]
46
+ def valid_header?(env)
47
+ env['HTTP_AUTHORIZATION'] =~ /\ABearer \S*\.\S*\.\S*\z/
54
48
  end
55
49
 
56
- def invalid_auth_header
57
- body = { error: "Invalid Authorization header format" }.to_json
58
- headers = {
59
- 'Content-Type' => 'application/json',
60
- 'Content-Length' => body.bytesize.to_s
61
- }
50
+ def return_error(message)
51
+ body = { error: message }.to_json
52
+ headers = { 'Content-Type' => 'application/json',
53
+ 'Content-Length' => body.bytesize.to_s }
62
54
 
63
- return [401, headers, [body]]
55
+ [401, headers, [body]]
64
56
  end
65
57
  end
66
58
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  module Jwt
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.1"
4
4
  end
5
5
  end
data/rack-jwt.gemspec CHANGED
@@ -17,9 +17,10 @@ Gem::Specification.new do |spec|
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
+ spec.required_ruby_version = '>= 1.9.3'
20
21
 
21
- spec.add_development_dependency "bundler", "~> 1.7"
22
- spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency 'bundler', '~> 1.7'
23
+ spec.add_development_dependency 'rake', '~> 10.0.0'
23
24
  spec.add_development_dependency 'rack-test', '~> 0.6.3'
24
25
  spec.add_development_dependency 'rspec', '~> 3.2.0'
25
26
 
data/spec/auth_spec.rb CHANGED
@@ -5,64 +5,107 @@ describe Rack::JWT::Auth do
5
5
 
6
6
  let(:issuer) { Rack::JWT::Token }
7
7
  let(:secret) { 'foo' }
8
+ let(:body) {{ 'foo' => 'bar' }}
8
9
 
9
10
  let(:app) do
10
- main_app = lambda { |env| [200, env, ['Hello']] }
11
- Rack::JWT::Auth.new(main_app, {secret: secret})
11
+ main_app = lambda { |env| [200, env, [body.to_json]] }
12
+ Rack::JWT::Auth.new(main_app, { secret: secret })
12
13
  end
13
14
 
14
- it 'raises an exception if no secret if provided' do
15
- expect{ Rack::JWT::Auth.new(main_app, {}) }.to raise_error
15
+ before do
16
+ get('/', {}, headers)
16
17
  end
17
18
 
18
- it 'returns 200 ok if the request is authenticated' do
19
- token = issuer.encode({ iss: 1 }, secret)
20
- get('/', {}, {'HTTP_AUTHORIZATION' => 'Bearer #{token}'})
19
+ context 'when no secret provided' do
20
+ let(:headers) { {} }
21
21
 
22
- expect(last_response.status).to eq 200
23
- expect(last_response.body).to eq 'Hello'
22
+ it 'raises an exception' do
23
+ expect{ Rack::JWT::Auth.new(main_app, {}) }.to raise_error
24
+ end
25
+ end
26
+
27
+ context 'when no authorization header provided' do
28
+ let(:headers) { {} }
29
+
30
+ subject { JSON.parse(last_response.body) }
24
31
 
25
- payload = last_response.header['jwt.payload']
32
+ it 'returns 401 status code' do
33
+ expect(last_response.status).to eq(401)
34
+ end
26
35
 
27
- expect(payload['iss']).to eql(1)
36
+ it 'returns an error message' do
37
+ expect(subject['error']).to eq('Missing Authorization header')
38
+ end
28
39
  end
29
40
 
30
- it 'returns 401 if the authorization header is missing' do
31
- get('/')
41
+ context 'when authorzation header does not contain the schema' do
42
+ let(:token) { issuer.encode({ iss: 1 }, secret) }
43
+ let(:headers) {{ 'HTTP_AUTHORIZATION' => token }}
32
44
 
33
- jsonResponse = JSON.parse(last_response.body)
45
+ subject { JSON.parse(last_response.body) }
34
46
 
35
- expect(last_response.status).to eql(401)
36
- expect(jsonResponse['error']).to eql('Missing Authorization header')
47
+ it 'returns 401 status code' do
48
+ expect(last_response.status).to eq(401)
49
+ end
50
+
51
+ it 'returns an error message' do
52
+ expect(subject['error']).to eq('Invalid Authorization header format')
53
+ end
37
54
  end
38
55
 
39
- it 'returns 401 if the authorization header signature is invalid' do
40
- token = issuer.encode({ iss: 1 }, 'invalid secret')
41
- get('/', {}, {'HTTP_AUTHORIZATION' => 'Bearer #{token}'})
56
+ context 'when authorization header contains an invalid schema' do
57
+ let(:token) { issuer.encode({ iss: 1 }, secret) }
58
+ let(:headers) {{ 'HTTP_AUTHORIZATION' => "WrongScheme #{token}" }}
59
+
60
+ subject { JSON.parse(last_response.body) }
42
61
 
43
- jsonResponse = JSON.parse(last_response.body)
62
+ it 'returns 401 status code' do
63
+ expect(last_response.status).to eq(401)
64
+ end
44
65
 
45
- expect(last_response.status).to eql(401)
46
- expect(jsonResponse['error']).to eql('Invalid JWT token')
66
+ it 'returns an error message' do
67
+ expect(subject['error']).to eq('Invalid Authorization header format')
68
+ end
47
69
  end
48
70
 
49
- it 'returns 401 if the header format is not Authorization: Bearer [token]' do
50
- token = issuer.encode({ iss: 1 }, secret)
51
- get('/', {}, {'HTTP_AUTHORIZATION' => '#{token}'})
71
+ context 'when token signature is invalid' do
72
+ let(:token) { issuer.encode({ iss: 1 }, 'invalid secret') }
73
+ let(:headers) {{ 'HTTP_AUTHORIZATION' => "Bearer #{token}" }}
52
74
 
53
- jsonResponse = JSON.parse(last_response.body)
75
+ subject { JSON.parse(last_response.body) }
54
76
 
55
- expect(last_response.status).to eql(401)
56
- expect(jsonResponse['error']).to eql('Invalid Authorization header format')
77
+ it 'returns 401 status code' do
78
+ expect(last_response.status).to eq(401)
79
+ end
80
+
81
+ it 'returns an error message' do
82
+ expect(subject['error']).to eq('Invalid JWT token')
83
+ end
57
84
  end
58
85
 
59
- it 'returns 401 if authorization scheme is not Bearer' do
60
- token = issuer.encode({ iss: 1 }, secret)
61
- get('/', {}, {'HTTP_AUTHORIZATION' => 'WrongScheme #{token}'})
86
+ context 'when token is valid' do
87
+ let(:token) { issuer.encode({ iss: 1 }, secret) }
88
+ let(:headers) {{ 'HTTP_AUTHORIZATION' => "Bearer #{token}" }}
89
+
90
+ subject { JSON.parse(last_response.body) }
91
+
92
+ it 'returns 200 status code' do
93
+ expect(last_response.status).to eq(200)
94
+ end
95
+
96
+ it 'process the request' do
97
+ expect(subject).to eq(body)
98
+ end
62
99
 
63
- jsonResponse = JSON.parse(last_response.body)
100
+ it 'adds the token payload to the request' do
101
+ payload = last_response.header['jwt.payload']
102
+ expect(payload['iss']).to eq(1)
103
+ end
64
104
 
65
- expect(last_response.status).to eql(401)
66
- expect(jsonResponse['error']).to eql('Invalid Authorization header format')
105
+ it 'adds the token header to the request' do
106
+ header = last_response.header['jwt.header']
107
+ expect(header['alg']).to eq('HS256')
108
+ expect(header['typ']).to eq('JWT')
109
+ end
67
110
  end
68
111
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-jwt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mr. Eigenbart
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-06 00:00:00.000000000 Z
11
+ date: 2015-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 10.0.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 10.0.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rack-test
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -103,6 +103,7 @@ extra_rdoc_files: []
103
103
  files:
104
104
  - ".gitignore"
105
105
  - ".rspec"
106
+ - ".travis.yml"
106
107
  - Gemfile
107
108
  - LICENSE.txt
108
109
  - README.md
@@ -126,7 +127,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
126
127
  requirements:
127
128
  - - ">="
128
129
  - !ruby/object:Gem::Version
129
- version: '0'
130
+ version: 1.9.3
130
131
  required_rubygems_version: !ruby/object:Gem::Requirement
131
132
  requirements:
132
133
  - - ">="