oauth2-rack 0.0.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oauth2-rack (0.0.5)
4
+ oauth2-rack (1.0.0)
5
5
  multi_json
6
6
  rack
7
7
 
@@ -0,0 +1,61 @@
1
+ require 'oauth2/rack'
2
+
3
+ # 7. Accessing Protected Resources
4
+ class OAuth2::Rack::Authentication::AccessToken::BearerHeader
5
+ HEADER_KEYS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION']
6
+
7
+ def initialize(app, opts = {}, &authenticator)
8
+ @app = app
9
+ @realm = opts[:realm]
10
+ @required = opts.fetch(:required, true)
11
+ @authenticator = authenticator || opts[:authenticator]
12
+ end
13
+
14
+ def call(env)
15
+ key = HEADER_KEYS.find { |k| env.has_key?(k) }
16
+ auth_string = env[key]
17
+
18
+ if auth_string.nil?
19
+ return @required ? error_response(:code => 400, :error => :invalid_request) : @app.call(env)
20
+ end
21
+
22
+ schema, credentials = auth_string.split(' ', 2)
23
+ if schema.downcase != 'bearer'
24
+ return error_response(:code => 400,
25
+ :error => :invalid_request)
26
+ end
27
+
28
+ access_token = @authenticator.call(:access_token => credentials)
29
+
30
+ if access_token.nil? || (access_token.is_a?(Hash) && access_token[:error])
31
+ error_response(access_token)
32
+ else
33
+ env['oauth2.access_token'] = access_token
34
+ @app.call(env)
35
+ end
36
+ end
37
+
38
+ private
39
+ def authenticate(opts)
40
+ @authenticator && @authenticator.call(opts)
41
+ end
42
+
43
+ def error_response(opts)
44
+ opts ||= {}
45
+ code = opts.delete(:code) || 401
46
+
47
+ opts[:realm] = @realm if @realm
48
+ opts[:error] ||= 'invalid_token'
49
+
50
+ [ code,
51
+ { 'Content-Type' => 'text/plain',
52
+ 'Content-Length' => '0',
53
+ 'WWW-Authenticate' => www_authenticate_header(opts) },
54
+ []
55
+ ]
56
+ end
57
+
58
+ def www_authenticate_header(opts)
59
+ 'Bearer ' + opts.collect { |k, v| %Q(#{k}=#{v.inspect}) }.join(',')
60
+ end
61
+ end
@@ -0,0 +1,4 @@
1
+ # Auth access token
2
+ module OAuth2::Rack::Authentication::AccessToken
3
+ autoload :BearerHeader, 'oauth2/rack/authentication/access_token/bearer_header'
4
+ end
@@ -2,5 +2,6 @@
2
2
  module OAuth2::Rack::Authentication
3
3
  autoload :Client, 'oauth2/rack/authentication/client'
4
4
  autoload :ResourceOwner, 'oauth2/rack/authentication/resource_owner'
5
+ autoload :AccessToken, 'oauth2/rack/authentication/access_token'
5
6
  end
6
7
 
@@ -27,6 +27,7 @@ class OAuth2::Rack::Authorization::ClientCredentials::AccessTokenIssuer
27
27
  if access_token['error']
28
28
  error_response(access_token)
29
29
  else
30
+ access_token['token_type'] ||= 'bearer'
30
31
  successful_response(access_token)
31
32
  end
32
33
  end
@@ -29,6 +29,7 @@ class OAuth2::Rack::Authorization::Password::AccessTokenIssuer
29
29
  if access_token['error']
30
30
  error_response(access_token)
31
31
  else
32
+ access_token['token_type'] ||= 'bearer'
32
33
  successful_response(access_token)
33
34
  end
34
35
  end
@@ -24,6 +24,7 @@ class OAuth2::Rack::Authorization::RefreshToken::AccessTokenIssuer
24
24
  if access_token['error']
25
25
  error_response(access_token)
26
26
  else
27
+ access_token['token_type'] ||= 'bearer'
27
28
  successful_response(access_token)
28
29
  end
29
30
  end
@@ -1,5 +1,5 @@
1
1
  module OAuth2
2
2
  module Rack
3
- VERSION = "0.0.5"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe OAuth2::Rack::Authentication::AccessToken::BearerHeader do
4
+ let(:access_token) { 'xxx' }
5
+ let(:authenticator) { double('authenticator').as_null_object }
6
+ let(:opts) { Hash.new }
7
+ let(:chained_app_response) { [200, { 'Content-Type' => 'text/plain' }, []] }
8
+
9
+ def do_request
10
+ post '/', opts
11
+ end
12
+
13
+ context 'when auth header is not specified' do
14
+ context 'and bearer auth is required' do
15
+ it 'responds with 401 unauthorized' do
16
+ do_request
17
+ response.status.should eq(400)
18
+ end
19
+ end
20
+ context 'and http basic auth is optional' do
21
+ app { OAuth2::Rack::Authentication::AccessToken::BearerHeader.new(chained_app, :required => false) }
22
+ it 'continues the app' do
23
+ chained_app.should_receive(:call).and_return(chained_app_response)
24
+ do_request
25
+ response.status.should eq(200)
26
+ end
27
+ end
28
+ end
29
+
30
+ context 'when schema is not bearer' do
31
+ before { opts['HTTP_AUTHORIZATION'] = 'Digest ' + access_token }
32
+
33
+ it 'responds with 400 bad request' do
34
+ do_request
35
+ response.status.should eq(400)
36
+ end
37
+ end
38
+
39
+ context 'when schema is bearer' do
40
+ app {
41
+ OAuth2::Rack::Authentication::AccessToken::BearerHeader.new(chained_app) do |opts|
42
+ authenticator.call(opts)
43
+ end
44
+ }
45
+ before { opts['HTTP_AUTHORIZATION'] = "Bearer #{access_token}" }
46
+
47
+ context 'and credentials are valid' do
48
+ it 'sets oauth2.client in env' do
49
+ authenticator.should_receive(:call).with(:access_token => access_token).and_return(access_token)
50
+ chained_app.should_receive(:call).with(hash_including('oauth2.access_token' => access_token)).and_return(chained_app_response)
51
+
52
+ do_request
53
+ end
54
+ end
55
+
56
+ context 'but credentials are invalid' do
57
+ it 'responds with 401 unauthorized' do
58
+ authenticator.should_receive(:call).with(:access_token => access_token).and_return(nil)
59
+ chained_app.should_not_receive(:call)
60
+
61
+ do_request
62
+
63
+ response.status.should eq(401)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -82,6 +82,12 @@ describe OAuth2::Rack::Authorization::ClientCredentials::AccessTokenIssuer do
82
82
  response.status.should eq(200)
83
83
  response_object['access_token'].should eq('X')
84
84
  end
85
+
86
+ it 'responds with default token type' do
87
+ do_request
88
+
89
+ response_object['token_type'].should eq('bearer')
90
+ end
85
91
  end
86
92
  end
87
93
  end
@@ -86,6 +86,12 @@ describe OAuth2::Rack::Authorization::Password::AccessTokenIssuer do
86
86
  response.status.should eq(200)
87
87
  response_object['access_token'].should eq('X')
88
88
  end
89
+
90
+ it 'responds with default token type' do
91
+ do_request
92
+
93
+ response_object['token_type'].should eq('bearer')
94
+ end
89
95
  end
90
96
  end
91
97
  end
@@ -86,6 +86,12 @@ describe OAuth2::Rack::Authorization::RefreshToken::AccessTokenIssuer do
86
86
  response.status.should eq(200)
87
87
  response_object['access_token'].should eq('X')
88
88
  end
89
+
90
+ it 'responds with default token type' do
91
+ do_request
92
+
93
+ response_object['token_type'].should eq('bearer')
94
+ end
89
95
  end
90
96
  end
91
97
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oauth2-rack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-01-20 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_json
16
- requirement: &2156611780 !ruby/object:Gem::Requirement
16
+ requirement: &2152919700 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2156611780
24
+ version_requirements: *2152919700
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rack
27
- requirement: &2156611280 !ruby/object:Gem::Requirement
27
+ requirement: &2152919200 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2156611280
35
+ version_requirements: *2152919200
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &2156592240 !ruby/object:Gem::Requirement
38
+ requirement: &2152918600 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2156592240
46
+ version_requirements: *2152918600
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &2156591700 !ruby/object:Gem::Requirement
49
+ requirement: &2152918080 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2156591700
57
+ version_requirements: *2152918080
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: yard
60
- requirement: &2156591120 !ruby/object:Gem::Requirement
60
+ requirement: &2152917440 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2156591120
68
+ version_requirements: *2152917440
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: shotgun
71
- requirement: &2156590520 !ruby/object:Gem::Requirement
71
+ requirement: &2152917000 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *2156590520
79
+ version_requirements: *2152917000
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: guard-rspec
82
- requirement: &2156589980 !ruby/object:Gem::Requirement
82
+ requirement: &2152916540 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *2156589980
90
+ version_requirements: *2152916540
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: oauth2
93
- requirement: &2156589380 !ruby/object:Gem::Requirement
93
+ requirement: &2152916060 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,7 +98,7 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *2156589380
101
+ version_requirements: *2152916060
102
102
  description: Rack middlewares for OAuth2 authorization server and resource server
103
103
  email:
104
104
  - me@iany.me
@@ -120,6 +120,8 @@ files:
120
120
  - lib/oauth2-rack.rb
121
121
  - lib/oauth2/rack.rb
122
122
  - lib/oauth2/rack/authentication.rb
123
+ - lib/oauth2/rack/authentication/access_token.rb
124
+ - lib/oauth2/rack/authentication/access_token/bearer_header.rb
123
125
  - lib/oauth2/rack/authentication/client.rb
124
126
  - lib/oauth2/rack/authentication/client/http_basic.rb
125
127
  - lib/oauth2/rack/authentication/client/request_params.rb
@@ -134,6 +136,7 @@ files:
134
136
  - lib/oauth2/rack/authorization/refresh_token/access_token_issuer.rb
135
137
  - lib/oauth2/rack/version.rb
136
138
  - oauth2-rack.gemspec
139
+ - spec/oauth2/rack/authentication/access_token/bearer_header_spec.rb
137
140
  - spec/oauth2/rack/authentication/client/http_basic_spec.rb
138
141
  - spec/oauth2/rack/authentication/client/request_params_spec.rb
139
142
  - spec/oauth2/rack/authentication/resource_owner/request_params_spec.rb
@@ -157,7 +160,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
157
160
  version: '0'
158
161
  segments:
159
162
  - 0
160
- hash: 2663607301986849054
163
+ hash: -744756891435917136
161
164
  required_rubygems_version: !ruby/object:Gem::Requirement
162
165
  none: false
163
166
  requirements:
@@ -166,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
169
  version: '0'
167
170
  segments:
168
171
  - 0
169
- hash: 2663607301986849054
172
+ hash: -744756891435917136
170
173
  requirements: []
171
174
  rubyforge_project: oauth2-rack
172
175
  rubygems_version: 1.8.10
@@ -174,6 +177,7 @@ signing_key:
174
177
  specification_version: 3
175
178
  summary: Rack middlewares for OAuth2 authorization server and resource server
176
179
  test_files:
180
+ - spec/oauth2/rack/authentication/access_token/bearer_header_spec.rb
177
181
  - spec/oauth2/rack/authentication/client/http_basic_spec.rb
178
182
  - spec/oauth2/rack/authentication/client/request_params_spec.rb
179
183
  - spec/oauth2/rack/authentication/resource_owner/request_params_spec.rb