oauth2-rack 0.0.5 → 1.0.0
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.lock +1 -1
- data/lib/oauth2/rack/authentication/access_token/bearer_header.rb +61 -0
- data/lib/oauth2/rack/authentication/access_token.rb +4 -0
- data/lib/oauth2/rack/authentication.rb +1 -0
- data/lib/oauth2/rack/authorization/client_credentials/access_token_issuer.rb +1 -0
- data/lib/oauth2/rack/authorization/password/access_token_issuer.rb +1 -0
- data/lib/oauth2/rack/authorization/refresh_token/access_token_issuer.rb +1 -0
- data/lib/oauth2/rack/version.rb +1 -1
- data/spec/oauth2/rack/authentication/access_token/bearer_header_spec.rb +67 -0
- data/spec/oauth2/rack/authorization/client_credentials/access_token_issuer_spec.rb +6 -0
- data/spec/oauth2/rack/authorization/password/access_token_issuer_spec.rb +6 -0
- data/spec/oauth2/rack/authorization/refresh_token/access_token_issuer_spec.rb +6 -0
- metadata +23 -19
data/Gemfile.lock
CHANGED
@@ -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
|
data/lib/oauth2/rack/version.rb
CHANGED
@@ -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
|
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: &
|
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: *
|
24
|
+
version_requirements: *2152919700
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rack
|
27
|
-
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: *
|
35
|
+
version_requirements: *2152919200
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rake
|
38
|
-
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: *
|
46
|
+
version_requirements: *2152918600
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rspec
|
49
|
-
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: *
|
57
|
+
version_requirements: *2152918080
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: yard
|
60
|
-
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: *
|
68
|
+
version_requirements: *2152917440
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: shotgun
|
71
|
-
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: *
|
79
|
+
version_requirements: *2152917000
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: guard-rspec
|
82
|
-
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: *
|
90
|
+
version_requirements: *2152916540
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: oauth2
|
93
|
-
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: *
|
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:
|
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:
|
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
|