rack-oauth2-revibe 1.0.7
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 +7 -0
- data/.document +5 -0
- data/.gitignore +22 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +7 -0
- data/LICENSE +20 -0
- data/README.rdoc +78 -0
- data/Rakefile +25 -0
- data/VERSION +1 -0
- data/lib/rack/oauth2.rb +67 -0
- data/lib/rack/oauth2/access_token.rb +36 -0
- data/lib/rack/oauth2/access_token/authenticator.rb +24 -0
- data/lib/rack/oauth2/access_token/bearer.rb +11 -0
- data/lib/rack/oauth2/access_token/legacy.rb +23 -0
- data/lib/rack/oauth2/access_token/mac.rb +103 -0
- data/lib/rack/oauth2/access_token/mac/sha256_hex_verifier.rb +17 -0
- data/lib/rack/oauth2/access_token/mac/signature.rb +34 -0
- data/lib/rack/oauth2/access_token/mac/verifier.rb +44 -0
- data/lib/rack/oauth2/client.rb +139 -0
- data/lib/rack/oauth2/client/error.rb +14 -0
- data/lib/rack/oauth2/client/grant.rb +30 -0
- data/lib/rack/oauth2/client/grant/authorization_code.rb +12 -0
- data/lib/rack/oauth2/client/grant/client_credentials.rb +10 -0
- data/lib/rack/oauth2/client/grant/facebook_token.rb +12 -0
- data/lib/rack/oauth2/client/grant/password.rb +11 -0
- data/lib/rack/oauth2/client/grant/refresh_token.rb +11 -0
- data/lib/rack/oauth2/debugger.rb +3 -0
- data/lib/rack/oauth2/debugger/request_filter.rb +30 -0
- data/lib/rack/oauth2/server.rb +4 -0
- data/lib/rack/oauth2/server/abstract.rb +4 -0
- data/lib/rack/oauth2/server/abstract/error.rb +69 -0
- data/lib/rack/oauth2/server/abstract/handler.rb +20 -0
- data/lib/rack/oauth2/server/abstract/request.rb +29 -0
- data/lib/rack/oauth2/server/abstract/response.rb +15 -0
- data/lib/rack/oauth2/server/authorize.rb +117 -0
- data/lib/rack/oauth2/server/authorize/code.rb +39 -0
- data/lib/rack/oauth2/server/authorize/error.rb +71 -0
- data/lib/rack/oauth2/server/authorize/extension.rb +12 -0
- data/lib/rack/oauth2/server/authorize/extension/code_and_token.rb +39 -0
- data/lib/rack/oauth2/server/authorize/token.rb +43 -0
- data/lib/rack/oauth2/server/resource.rb +55 -0
- data/lib/rack/oauth2/server/resource/bearer.rb +47 -0
- data/lib/rack/oauth2/server/resource/bearer/error.rb +24 -0
- data/lib/rack/oauth2/server/resource/error.rb +81 -0
- data/lib/rack/oauth2/server/resource/mac.rb +36 -0
- data/lib/rack/oauth2/server/resource/mac/error.rb +24 -0
- data/lib/rack/oauth2/server/token.rb +87 -0
- data/lib/rack/oauth2/server/token/authorization_code.rb +28 -0
- data/lib/rack/oauth2/server/token/client_credentials.rb +23 -0
- data/lib/rack/oauth2/server/token/error.rb +54 -0
- data/lib/rack/oauth2/server/token/extension.rb +12 -0
- data/lib/rack/oauth2/server/token/extension/jwt.rb +37 -0
- data/lib/rack/oauth2/server/token/facebook_token.rb +27 -0
- data/lib/rack/oauth2/server/token/password.rb +27 -0
- data/lib/rack/oauth2/server/token/refresh_token.rb +26 -0
- data/lib/rack/oauth2/util.rb +58 -0
- data/rack-oauth2.gemspec +30 -0
- data/spec/helpers/time.rb +19 -0
- data/spec/helpers/webmock_helper.rb +41 -0
- data/spec/mock_response/blank +0 -0
- data/spec/mock_response/errors/invalid_request.json +4 -0
- data/spec/mock_response/resources/fake.txt +1 -0
- data/spec/mock_response/tokens/_Bearer.json +6 -0
- data/spec/mock_response/tokens/bearer.json +6 -0
- data/spec/mock_response/tokens/legacy.json +5 -0
- data/spec/mock_response/tokens/legacy.txt +1 -0
- data/spec/mock_response/tokens/legacy_without_expires_in.txt +1 -0
- data/spec/mock_response/tokens/mac.json +8 -0
- data/spec/mock_response/tokens/unknown.json +6 -0
- data/spec/rack/oauth2/access_token/authenticator_spec.rb +43 -0
- data/spec/rack/oauth2/access_token/bearer_spec.rb +18 -0
- data/spec/rack/oauth2/access_token/legacy_spec.rb +23 -0
- data/spec/rack/oauth2/access_token/mac/sha256_hex_verifier_spec.rb +28 -0
- data/spec/rack/oauth2/access_token/mac/signature_spec.rb +59 -0
- data/spec/rack/oauth2/access_token/mac/verifier_spec.rb +25 -0
- data/spec/rack/oauth2/access_token/mac_spec.rb +141 -0
- data/spec/rack/oauth2/access_token_spec.rb +69 -0
- data/spec/rack/oauth2/client/error_spec.rb +18 -0
- data/spec/rack/oauth2/client/grant/authorization_code_spec.rb +37 -0
- data/spec/rack/oauth2/client/grant/client_credentials_spec.rb +7 -0
- data/spec/rack/oauth2/client/grant/password_spec.rb +33 -0
- data/spec/rack/oauth2/client/grant/refresh_token_spec.rb +21 -0
- data/spec/rack/oauth2/client_spec.rb +287 -0
- data/spec/rack/oauth2/debugger/request_filter_spec.rb +33 -0
- data/spec/rack/oauth2/oauth2_spec.rb +74 -0
- data/spec/rack/oauth2/server/abstract/error_spec.rb +59 -0
- data/spec/rack/oauth2/server/authorize/code_spec.rb +57 -0
- data/spec/rack/oauth2/server/authorize/error_spec.rb +103 -0
- data/spec/rack/oauth2/server/authorize/extensions/code_and_token_spec.rb +60 -0
- data/spec/rack/oauth2/server/authorize/token_spec.rb +73 -0
- data/spec/rack/oauth2/server/authorize_spec.rb +214 -0
- data/spec/rack/oauth2/server/resource/bearer/error_spec.rb +52 -0
- data/spec/rack/oauth2/server/resource/bearer_spec.rb +123 -0
- data/spec/rack/oauth2/server/resource/error_spec.rb +147 -0
- data/spec/rack/oauth2/server/resource/mac/error_spec.rb +52 -0
- data/spec/rack/oauth2/server/resource/mac_spec.rb +119 -0
- data/spec/rack/oauth2/server/resource_spec.rb +23 -0
- data/spec/rack/oauth2/server/token/authorization_code_spec.rb +43 -0
- data/spec/rack/oauth2/server/token/client_credentials_spec.rb +23 -0
- data/spec/rack/oauth2/server/token/error_spec.rb +77 -0
- data/spec/rack/oauth2/server/token/password_spec.rb +37 -0
- data/spec/rack/oauth2/server/token/refresh_token_spec.rb +34 -0
- data/spec/rack/oauth2/server/token_spec.rb +134 -0
- data/spec/rack/oauth2/util_spec.rb +97 -0
- data/spec/spec_helper.rb +14 -0
- metadata +326 -0
@@ -0,0 +1,214 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe Rack::OAuth2::Server::Authorize do
|
4
|
+
let(:app) { Rack::OAuth2::Server::Authorize.new }
|
5
|
+
let(:request) { Rack::MockRequest.new app }
|
6
|
+
let(:redirect_uri) { 'http://client.example.com/callback' }
|
7
|
+
let(:bad_request) { Rack::OAuth2::Server::Authorize::BadRequest }
|
8
|
+
|
9
|
+
context 'when response_type is missing' do
|
10
|
+
it do
|
11
|
+
expect { request.get "/?client_id=client&redirect_uri=#{redirect_uri}" }.to raise_error bad_request
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when redirect_uri is missing' do
|
16
|
+
it do
|
17
|
+
expect { request.get "/?response_type=code&client_id=client" }.not_to raise_error
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when client_id is missing' do
|
22
|
+
it do
|
23
|
+
expect { request.get "/?response_type=code&redirect_uri=#{redirect_uri}" }.to raise_error bad_request
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when unknown response_type is given' do
|
28
|
+
it do
|
29
|
+
expect { request.get "/?response_type=unknown&client_id=client&redirect_uri=#{redirect_uri}" }.to raise_error bad_request
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when all required parameters are valid' do
|
34
|
+
[:code, :token].each do |request_type|
|
35
|
+
context "when response_type = :#{request_type}" do
|
36
|
+
subject { request.get "/?response_type=#{request_type}&client_id=client&redirect_uri=#{redirect_uri}" }
|
37
|
+
its(:status) { should == 200 }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe Rack::OAuth2::Server::Authorize::Request do
|
43
|
+
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client&redirect_uri=#{redirect_uri}") }
|
44
|
+
let(:request) { Rack::OAuth2::Server::Authorize::Request.new env }
|
45
|
+
|
46
|
+
describe '#varified_redirect_uri' do
|
47
|
+
context 'when an Array of pre-registered URIs are given' do
|
48
|
+
context 'when given redirect_uri is valid against one of them' do
|
49
|
+
let :pre_registered do
|
50
|
+
[
|
51
|
+
redirect_uri,
|
52
|
+
'http://ja.client.example.com/callback',
|
53
|
+
'http://en.client.example.com/callback'
|
54
|
+
]
|
55
|
+
end
|
56
|
+
it 'should be valid' do
|
57
|
+
request.verify_redirect_uri!(pre_registered).should == redirect_uri
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'otherwise' do
|
62
|
+
let :pre_registered do
|
63
|
+
[
|
64
|
+
'http://ja.client.example.com/callback',
|
65
|
+
'http://en.client.example.com/callback'
|
66
|
+
]
|
67
|
+
end
|
68
|
+
it do
|
69
|
+
expect do
|
70
|
+
request.verify_redirect_uri!(pre_registered)
|
71
|
+
end.to raise_error bad_request
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'when exact mathed redirect_uri is given' do
|
77
|
+
let(:pre_registered) { redirect_uri }
|
78
|
+
it 'should be valid' do
|
79
|
+
request.verify_redirect_uri!(pre_registered).should == redirect_uri
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when partially mathed redirect_uri is given' do
|
84
|
+
let(:pre_registered) { 'http://client.example.com' }
|
85
|
+
|
86
|
+
context 'when partial matching allowed' do
|
87
|
+
it 'should be valid' do
|
88
|
+
request.verify_redirect_uri!(pre_registered, :allow_partial_match).should == redirect_uri
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'otherwise' do
|
93
|
+
it do
|
94
|
+
expect do
|
95
|
+
request.verify_redirect_uri!(pre_registered)
|
96
|
+
end.to raise_error bad_request
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'when invalid redirect_uri is given' do
|
102
|
+
let(:pre_registered) { 'http://client2.example.com' }
|
103
|
+
it do
|
104
|
+
expect do
|
105
|
+
request.verify_redirect_uri!(pre_registered)
|
106
|
+
end.to raise_error bad_request
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'when redirect_uri is missing' do
|
111
|
+
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client") }
|
112
|
+
|
113
|
+
context 'when pre-registered redirect_uri is a String' do
|
114
|
+
let(:pre_registered) { redirect_uri }
|
115
|
+
it 'should use pre-registered redirect_uri' do
|
116
|
+
request.verify_redirect_uri!(pre_registered).should == pre_registered
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'when pre-registered redirect_uri is an Array' do
|
121
|
+
context 'when only 1' do
|
122
|
+
let(:pre_registered) { [redirect_uri] }
|
123
|
+
|
124
|
+
context 'when partial match allowed' do
|
125
|
+
it do
|
126
|
+
expect do
|
127
|
+
request.verify_redirect_uri!(pre_registered, :allow_partial_match)
|
128
|
+
end.to raise_error bad_request
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'otherwise' do
|
133
|
+
it 'should use pre-registered redirect_uri' do
|
134
|
+
request.verify_redirect_uri!(pre_registered).should == pre_registered.first
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'when more than 2' do
|
140
|
+
let(:pre_registered) { [redirect_uri, 'http://client.example.com/callback2'] }
|
141
|
+
it do
|
142
|
+
expect do
|
143
|
+
request.verify_redirect_uri!(pre_registered)
|
144
|
+
end.to raise_error bad_request
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe 'extensibility' do
|
153
|
+
before do
|
154
|
+
require 'rack/oauth2/server/authorize/extension/code_and_token'
|
155
|
+
end
|
156
|
+
|
157
|
+
let(:env) do
|
158
|
+
Rack::MockRequest.env_for("/authorize?response_type=#{response_type}&client_id=client")
|
159
|
+
end
|
160
|
+
let(:request) { Rack::OAuth2::Server::Authorize::Request.new env }
|
161
|
+
its(:extensions) { should == [Rack::OAuth2::Server::Authorize::Extension::CodeAndToken] }
|
162
|
+
|
163
|
+
describe 'code token' do
|
164
|
+
let(:response_type) { 'code%20token' }
|
165
|
+
it do
|
166
|
+
app.send(
|
167
|
+
:response_type_for, request
|
168
|
+
).should == Rack::OAuth2::Server::Authorize::Extension::CodeAndToken
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe 'token code' do
|
173
|
+
let(:response_type) { 'token%20code' }
|
174
|
+
it do
|
175
|
+
app.send(
|
176
|
+
:response_type_for, request
|
177
|
+
).should == Rack::OAuth2::Server::Authorize::Extension::CodeAndToken
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe 'token code id_token' do
|
182
|
+
let(:response_type) { 'token%20code%20id_token' }
|
183
|
+
it do
|
184
|
+
expect do
|
185
|
+
app.send(:response_type_for, request)
|
186
|
+
end.to raise_error bad_request
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe 'id_token' do
|
191
|
+
before do
|
192
|
+
class Rack::OAuth2::Server::Authorize::Extension::IdToken < Rack::OAuth2::Server::Abstract::Handler
|
193
|
+
def self.response_type_for?(response_type)
|
194
|
+
response_type == 'id_token'
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
its(:extensions) do
|
200
|
+
should == [
|
201
|
+
Rack::OAuth2::Server::Authorize::Extension::CodeAndToken,
|
202
|
+
Rack::OAuth2::Server::Authorize::Extension::IdToken
|
203
|
+
]
|
204
|
+
end
|
205
|
+
|
206
|
+
let(:response_type) { 'id_token' }
|
207
|
+
it do
|
208
|
+
app.send(
|
209
|
+
:response_type_for, request
|
210
|
+
).should == Rack::OAuth2::Server::Authorize::Extension::IdToken
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe Rack::OAuth2::Server::Resource::Bearer::Unauthorized do
|
4
|
+
let(:error) { Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new(:invalid_token) }
|
5
|
+
|
6
|
+
it { should be_a Rack::OAuth2::Server::Resource::Unauthorized }
|
7
|
+
|
8
|
+
describe '#scheme' do
|
9
|
+
subject { error }
|
10
|
+
its(:scheme) { should == :Bearer }
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#finish' do
|
14
|
+
it 'should use Bearer scheme' do
|
15
|
+
status, header, response = error.finish
|
16
|
+
header['WWW-Authenticate'].should include 'Bearer'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe Rack::OAuth2::Server::Resource::Bearer::ErrorMethods do
|
22
|
+
let(:unauthorized) { Rack::OAuth2::Server::Resource::Bearer::Unauthorized }
|
23
|
+
let(:redirect_uri) { 'http://client.example.com/callback' }
|
24
|
+
let(:default_description) { Rack::OAuth2::Server::Resource::ErrorMethods::DEFAULT_DESCRIPTION }
|
25
|
+
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client_id") }
|
26
|
+
let(:request) { Rack::OAuth2::Server::Resource::Bearer::Request.new env }
|
27
|
+
|
28
|
+
describe 'unauthorized!' do
|
29
|
+
it do
|
30
|
+
expect { request.unauthorized! :invalid_client }.to raise_error unauthorized
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
Rack::OAuth2::Server::Resource::Bearer::ErrorMethods::DEFAULT_DESCRIPTION.keys.each do |error_code|
|
35
|
+
method = "#{error_code}!"
|
36
|
+
case error_code
|
37
|
+
when :invalid_request
|
38
|
+
# ignore
|
39
|
+
when :insufficient_scope
|
40
|
+
# ignore
|
41
|
+
else
|
42
|
+
describe method do
|
43
|
+
it "should raise Rack::OAuth2::Server::Resource::Bearer::Unauthorized with error = :#{error_code}" do
|
44
|
+
expect { request.send method }.to raise_error(unauthorized) { |error|
|
45
|
+
error.error.should == error_code
|
46
|
+
error.description.should == default_description[error_code]
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe Rack::OAuth2::Server::Resource::Bearer do
|
4
|
+
let(:app) do
|
5
|
+
Rack::OAuth2::Server::Resource::Bearer.new(simple_app) do |request|
|
6
|
+
case request.access_token
|
7
|
+
when 'valid_token'
|
8
|
+
bearer_token
|
9
|
+
when 'insufficient_scope_token'
|
10
|
+
request.insufficient_scope!
|
11
|
+
else
|
12
|
+
request.invalid_token!
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
let(:bearer_token) do
|
17
|
+
Rack::OAuth2::AccessToken::Bearer.new(:access_token => 'valid_token')
|
18
|
+
end
|
19
|
+
let(:access_token) { env[Rack::OAuth2::Server::Resource::ACCESS_TOKEN] }
|
20
|
+
let(:request) { app.call(env) }
|
21
|
+
subject { app.call(env) }
|
22
|
+
|
23
|
+
shared_examples_for :authenticated_bearer_request do
|
24
|
+
it 'should be authenticated' do
|
25
|
+
status, header, response = request
|
26
|
+
status.should == 200
|
27
|
+
access_token.should == bearer_token
|
28
|
+
end
|
29
|
+
end
|
30
|
+
shared_examples_for :unauthorized_bearer_request do
|
31
|
+
it 'should be unauthorized' do
|
32
|
+
status, header, response = request
|
33
|
+
status.should == 401
|
34
|
+
header['WWW-Authenticate'].should include 'Bearer'
|
35
|
+
access_token.should be_nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
shared_examples_for :bad_bearer_request do
|
39
|
+
it 'should be bad_request' do
|
40
|
+
status, header, response = request
|
41
|
+
status.should == 400
|
42
|
+
access_token.should be_nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
shared_examples_for :skipped_authentication_request do
|
46
|
+
it 'should skip OAuth 2.0 authentication' do
|
47
|
+
status, header, response = request
|
48
|
+
status.should == 200
|
49
|
+
access_token.should be_nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when no access token is given' do
|
54
|
+
let(:env) { Rack::MockRequest.env_for('/protected_resource') }
|
55
|
+
it_behaves_like :skipped_authentication_request
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when valid_token is given' do
|
59
|
+
context 'when token is in Authorization header' do
|
60
|
+
let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'Bearer valid_token') }
|
61
|
+
it_behaves_like :authenticated_bearer_request
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when token is in params' do
|
65
|
+
let(:env) { Rack::MockRequest.env_for('/protected_resource', :params => {:access_token => 'valid_token'}) }
|
66
|
+
it_behaves_like :authenticated_bearer_request
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'when invalid authorization header is given' do
|
71
|
+
let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => '') }
|
72
|
+
it_behaves_like :skipped_authentication_request
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when invalid_token is given' do
|
76
|
+
let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'Bearer invalid_token') }
|
77
|
+
|
78
|
+
context 'when token is in Authorization header' do
|
79
|
+
it_behaves_like :unauthorized_bearer_request
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when token is in params' do
|
83
|
+
let(:env) { Rack::MockRequest.env_for('/protected_resource', :params => {:access_token => 'invalid_token'}) }
|
84
|
+
it_behaves_like :unauthorized_bearer_request
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'realm' do
|
88
|
+
|
89
|
+
context 'when specified' do
|
90
|
+
let(:realm) { 'server.example.com' }
|
91
|
+
let(:app) do
|
92
|
+
Rack::OAuth2::Server::Resource::Bearer.new(simple_app, realm) do |request|
|
93
|
+
request.unauthorized!
|
94
|
+
end
|
95
|
+
end
|
96
|
+
it 'should use specified realm' do
|
97
|
+
status, header, response = request
|
98
|
+
header['WWW-Authenticate'].should include "Bearer realm=\"#{realm}\""
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'otherwize' do
|
103
|
+
it 'should use default realm' do
|
104
|
+
status, header, response = request
|
105
|
+
header['WWW-Authenticate'].should include "Bearer realm=\"#{Rack::OAuth2::Server::Resource::Bearer::DEFAULT_REALM}\""
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'when multiple access_token is given' do
|
112
|
+
context 'when token is in Authorization header and params' do
|
113
|
+
let(:env) do
|
114
|
+
Rack::MockRequest.env_for(
|
115
|
+
'/protected_resource',
|
116
|
+
'HTTP_AUTHORIZATION' => 'Bearer valid_token',
|
117
|
+
:params => {:access_token => 'valid_token'}
|
118
|
+
)
|
119
|
+
end
|
120
|
+
it_behaves_like :bad_bearer_request
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe Rack::OAuth2::Server::Resource::BadRequest do
|
4
|
+
let(:error) { Rack::OAuth2::Server::Resource::BadRequest.new(:invalid_request) }
|
5
|
+
|
6
|
+
it { should be_a Rack::OAuth2::Server::Abstract::BadRequest }
|
7
|
+
|
8
|
+
describe '#finish' do
|
9
|
+
it 'should respond in JSON' do
|
10
|
+
status, header, response = error.finish
|
11
|
+
status.should == 400
|
12
|
+
header['Content-Type'].should == 'application/json'
|
13
|
+
response.body.should == ['{"error":"invalid_request"}']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe Rack::OAuth2::Server::Resource::Unauthorized do
|
19
|
+
let(:error) { Rack::OAuth2::Server::Resource::Unauthorized.new(:invalid_token) }
|
20
|
+
let(:realm) { Rack::OAuth2::Server::Resource::DEFAULT_REALM }
|
21
|
+
|
22
|
+
it { should be_a Rack::OAuth2::Server::Abstract::Unauthorized }
|
23
|
+
|
24
|
+
describe '#scheme' do
|
25
|
+
it do
|
26
|
+
expect { error.scheme }.to raise_error(RuntimeError, 'Define me!')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when scheme is defined' do
|
31
|
+
let :error_with_scheme do
|
32
|
+
e = error
|
33
|
+
e.instance_eval do
|
34
|
+
def scheme
|
35
|
+
:Scheme
|
36
|
+
end
|
37
|
+
end
|
38
|
+
e
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#finish' do
|
42
|
+
it 'should respond in JSON' do
|
43
|
+
status, header, response = error_with_scheme.finish
|
44
|
+
status.should == 401
|
45
|
+
header['Content-Type'].should == 'application/json'
|
46
|
+
header['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\", error=\"invalid_token\""
|
47
|
+
response.body.should == ['{"error":"invalid_token"}']
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when error_code is not invalid_token' do
|
51
|
+
let(:error) { Rack::OAuth2::Server::Resource::Unauthorized.new(:something) }
|
52
|
+
|
53
|
+
it 'should have error_code in body but not in WWW-Authenticate header' do
|
54
|
+
status, header, response = error_with_scheme.finish
|
55
|
+
header['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\""
|
56
|
+
response.body.first.should include '"error":"something"'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'when realm is specified' do
|
61
|
+
let(:realm) { 'server.example.com' }
|
62
|
+
let(:error) { Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new(:something, nil, :realm => realm) }
|
63
|
+
|
64
|
+
it 'should use given realm' do
|
65
|
+
status, header, response = error_with_scheme.finish
|
66
|
+
header['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\""
|
67
|
+
response.body.first.should include '"error":"something"'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe Rack::OAuth2::Server::Resource::Forbidden do
|
75
|
+
let(:error) { Rack::OAuth2::Server::Resource::Forbidden.new(:insufficient_scope) }
|
76
|
+
|
77
|
+
it { should be_a Rack::OAuth2::Server::Abstract::Forbidden }
|
78
|
+
|
79
|
+
describe '#finish' do
|
80
|
+
it 'should respond in JSON' do
|
81
|
+
status, header, response = error.finish
|
82
|
+
status.should == 403
|
83
|
+
header['Content-Type'].should == 'application/json'
|
84
|
+
response.body.should == ['{"error":"insufficient_scope"}']
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when scope option is given' do
|
89
|
+
let(:error) { Rack::OAuth2::Server::Resource::Bearer::Forbidden.new(:insufficient_scope, 'Desc', :scope => [:scope1, :scope2]) }
|
90
|
+
|
91
|
+
it 'should have blank WWW-Authenticate header' do
|
92
|
+
status, header, response = error.finish
|
93
|
+
response.body.first.should include '"scope":"scope1 scope2"'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe Rack::OAuth2::Server::Resource::Bearer::ErrorMethods do
|
99
|
+
let(:bad_request) { Rack::OAuth2::Server::Resource::BadRequest }
|
100
|
+
let(:forbidden) { Rack::OAuth2::Server::Resource::Forbidden }
|
101
|
+
let(:redirect_uri) { 'http://client.example.com/callback' }
|
102
|
+
let(:default_description) { Rack::OAuth2::Server::Resource::ErrorMethods::DEFAULT_DESCRIPTION }
|
103
|
+
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client_id") }
|
104
|
+
let(:request) { Rack::OAuth2::Server::Resource::Request.new env }
|
105
|
+
|
106
|
+
describe 'bad_request!' do
|
107
|
+
it do
|
108
|
+
expect { request.bad_request! :invalid_request }.to raise_error bad_request
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe 'unauthorized!' do
|
113
|
+
it do
|
114
|
+
expect { request.unauthorized! :invalid_client }.to raise_error(RuntimeError, 'Define me!')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
Rack::OAuth2::Server::Resource::ErrorMethods::DEFAULT_DESCRIPTION.keys.each do |error_code|
|
119
|
+
method = "#{error_code}!"
|
120
|
+
case error_code
|
121
|
+
when :invalid_request
|
122
|
+
describe method do
|
123
|
+
it "should raise Rack::OAuth2::Server::Resource::BadRequest with error = :#{error_code}" do
|
124
|
+
expect { request.send method }.to raise_error(bad_request) { |error|
|
125
|
+
error.error.should == error_code
|
126
|
+
error.description.should == default_description[error_code]
|
127
|
+
}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
when :insufficient_scope
|
131
|
+
describe method do
|
132
|
+
it "should raise Rack::OAuth2::Server::Resource::Forbidden with error = :#{error_code}" do
|
133
|
+
expect { request.send method }.to raise_error(forbidden) { |error|
|
134
|
+
error.error.should == error_code
|
135
|
+
error.description.should == default_description[error_code]
|
136
|
+
}
|
137
|
+
end
|
138
|
+
end
|
139
|
+
else
|
140
|
+
describe method do
|
141
|
+
it do
|
142
|
+
expect { request.send method }.to raise_error(RuntimeError, 'Define me!')
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|