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.
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