rack-oauth2-revibe 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.gitignore +22 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +3 -0
  6. data/Gemfile +7 -0
  7. data/LICENSE +20 -0
  8. data/README.rdoc +78 -0
  9. data/Rakefile +25 -0
  10. data/VERSION +1 -0
  11. data/lib/rack/oauth2.rb +67 -0
  12. data/lib/rack/oauth2/access_token.rb +36 -0
  13. data/lib/rack/oauth2/access_token/authenticator.rb +24 -0
  14. data/lib/rack/oauth2/access_token/bearer.rb +11 -0
  15. data/lib/rack/oauth2/access_token/legacy.rb +23 -0
  16. data/lib/rack/oauth2/access_token/mac.rb +103 -0
  17. data/lib/rack/oauth2/access_token/mac/sha256_hex_verifier.rb +17 -0
  18. data/lib/rack/oauth2/access_token/mac/signature.rb +34 -0
  19. data/lib/rack/oauth2/access_token/mac/verifier.rb +44 -0
  20. data/lib/rack/oauth2/client.rb +139 -0
  21. data/lib/rack/oauth2/client/error.rb +14 -0
  22. data/lib/rack/oauth2/client/grant.rb +30 -0
  23. data/lib/rack/oauth2/client/grant/authorization_code.rb +12 -0
  24. data/lib/rack/oauth2/client/grant/client_credentials.rb +10 -0
  25. data/lib/rack/oauth2/client/grant/facebook_token.rb +12 -0
  26. data/lib/rack/oauth2/client/grant/password.rb +11 -0
  27. data/lib/rack/oauth2/client/grant/refresh_token.rb +11 -0
  28. data/lib/rack/oauth2/debugger.rb +3 -0
  29. data/lib/rack/oauth2/debugger/request_filter.rb +30 -0
  30. data/lib/rack/oauth2/server.rb +4 -0
  31. data/lib/rack/oauth2/server/abstract.rb +4 -0
  32. data/lib/rack/oauth2/server/abstract/error.rb +69 -0
  33. data/lib/rack/oauth2/server/abstract/handler.rb +20 -0
  34. data/lib/rack/oauth2/server/abstract/request.rb +29 -0
  35. data/lib/rack/oauth2/server/abstract/response.rb +15 -0
  36. data/lib/rack/oauth2/server/authorize.rb +117 -0
  37. data/lib/rack/oauth2/server/authorize/code.rb +39 -0
  38. data/lib/rack/oauth2/server/authorize/error.rb +71 -0
  39. data/lib/rack/oauth2/server/authorize/extension.rb +12 -0
  40. data/lib/rack/oauth2/server/authorize/extension/code_and_token.rb +39 -0
  41. data/lib/rack/oauth2/server/authorize/token.rb +43 -0
  42. data/lib/rack/oauth2/server/resource.rb +55 -0
  43. data/lib/rack/oauth2/server/resource/bearer.rb +47 -0
  44. data/lib/rack/oauth2/server/resource/bearer/error.rb +24 -0
  45. data/lib/rack/oauth2/server/resource/error.rb +81 -0
  46. data/lib/rack/oauth2/server/resource/mac.rb +36 -0
  47. data/lib/rack/oauth2/server/resource/mac/error.rb +24 -0
  48. data/lib/rack/oauth2/server/token.rb +87 -0
  49. data/lib/rack/oauth2/server/token/authorization_code.rb +28 -0
  50. data/lib/rack/oauth2/server/token/client_credentials.rb +23 -0
  51. data/lib/rack/oauth2/server/token/error.rb +54 -0
  52. data/lib/rack/oauth2/server/token/extension.rb +12 -0
  53. data/lib/rack/oauth2/server/token/extension/jwt.rb +37 -0
  54. data/lib/rack/oauth2/server/token/facebook_token.rb +27 -0
  55. data/lib/rack/oauth2/server/token/password.rb +27 -0
  56. data/lib/rack/oauth2/server/token/refresh_token.rb +26 -0
  57. data/lib/rack/oauth2/util.rb +58 -0
  58. data/rack-oauth2.gemspec +30 -0
  59. data/spec/helpers/time.rb +19 -0
  60. data/spec/helpers/webmock_helper.rb +41 -0
  61. data/spec/mock_response/blank +0 -0
  62. data/spec/mock_response/errors/invalid_request.json +4 -0
  63. data/spec/mock_response/resources/fake.txt +1 -0
  64. data/spec/mock_response/tokens/_Bearer.json +6 -0
  65. data/spec/mock_response/tokens/bearer.json +6 -0
  66. data/spec/mock_response/tokens/legacy.json +5 -0
  67. data/spec/mock_response/tokens/legacy.txt +1 -0
  68. data/spec/mock_response/tokens/legacy_without_expires_in.txt +1 -0
  69. data/spec/mock_response/tokens/mac.json +8 -0
  70. data/spec/mock_response/tokens/unknown.json +6 -0
  71. data/spec/rack/oauth2/access_token/authenticator_spec.rb +43 -0
  72. data/spec/rack/oauth2/access_token/bearer_spec.rb +18 -0
  73. data/spec/rack/oauth2/access_token/legacy_spec.rb +23 -0
  74. data/spec/rack/oauth2/access_token/mac/sha256_hex_verifier_spec.rb +28 -0
  75. data/spec/rack/oauth2/access_token/mac/signature_spec.rb +59 -0
  76. data/spec/rack/oauth2/access_token/mac/verifier_spec.rb +25 -0
  77. data/spec/rack/oauth2/access_token/mac_spec.rb +141 -0
  78. data/spec/rack/oauth2/access_token_spec.rb +69 -0
  79. data/spec/rack/oauth2/client/error_spec.rb +18 -0
  80. data/spec/rack/oauth2/client/grant/authorization_code_spec.rb +37 -0
  81. data/spec/rack/oauth2/client/grant/client_credentials_spec.rb +7 -0
  82. data/spec/rack/oauth2/client/grant/password_spec.rb +33 -0
  83. data/spec/rack/oauth2/client/grant/refresh_token_spec.rb +21 -0
  84. data/spec/rack/oauth2/client_spec.rb +287 -0
  85. data/spec/rack/oauth2/debugger/request_filter_spec.rb +33 -0
  86. data/spec/rack/oauth2/oauth2_spec.rb +74 -0
  87. data/spec/rack/oauth2/server/abstract/error_spec.rb +59 -0
  88. data/spec/rack/oauth2/server/authorize/code_spec.rb +57 -0
  89. data/spec/rack/oauth2/server/authorize/error_spec.rb +103 -0
  90. data/spec/rack/oauth2/server/authorize/extensions/code_and_token_spec.rb +60 -0
  91. data/spec/rack/oauth2/server/authorize/token_spec.rb +73 -0
  92. data/spec/rack/oauth2/server/authorize_spec.rb +214 -0
  93. data/spec/rack/oauth2/server/resource/bearer/error_spec.rb +52 -0
  94. data/spec/rack/oauth2/server/resource/bearer_spec.rb +123 -0
  95. data/spec/rack/oauth2/server/resource/error_spec.rb +147 -0
  96. data/spec/rack/oauth2/server/resource/mac/error_spec.rb +52 -0
  97. data/spec/rack/oauth2/server/resource/mac_spec.rb +119 -0
  98. data/spec/rack/oauth2/server/resource_spec.rb +23 -0
  99. data/spec/rack/oauth2/server/token/authorization_code_spec.rb +43 -0
  100. data/spec/rack/oauth2/server/token/client_credentials_spec.rb +23 -0
  101. data/spec/rack/oauth2/server/token/error_spec.rb +77 -0
  102. data/spec/rack/oauth2/server/token/password_spec.rb +37 -0
  103. data/spec/rack/oauth2/server/token/refresh_token_spec.rb +34 -0
  104. data/spec/rack/oauth2/server/token_spec.rb +134 -0
  105. data/spec/rack/oauth2/util_spec.rb +97 -0
  106. data/spec/spec_helper.rb +14 -0
  107. 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