rack-oauth2 1.17.0 → 2.2.1
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 +4 -4
- data/.github/FUNDING.yml +3 -0
- data/.github/workflows/spec.yml +31 -0
- data/CHANGELOG.md +31 -0
- data/README.rdoc +1 -20
- data/VERSION +1 -1
- data/lib/rack/oauth2/access_token/authenticator.rb +1 -10
- data/lib/rack/oauth2/access_token/bearer.rb +1 -1
- data/lib/rack/oauth2/access_token/mtls.rb +2 -2
- data/lib/rack/oauth2/access_token.rb +4 -6
- data/lib/rack/oauth2/client.rb +86 -38
- data/lib/rack/oauth2/server/abstract/error.rb +2 -1
- data/lib/rack/oauth2/server/extension/pkce.rb +1 -1
- data/lib/rack/oauth2/server/rails/response_ext.rb +3 -3
- data/lib/rack/oauth2/server/resource/error.rb +4 -4
- data/lib/rack/oauth2/server/resource.rb +0 -1
- data/lib/rack/oauth2/server/token/error.rb +3 -1
- data/lib/rack/oauth2/server/token.rb +13 -4
- data/lib/rack/oauth2.rb +11 -10
- data/rack-oauth2.gemspec +6 -4
- data/spec/helpers/webmock_helper.rb +8 -2
- data/spec/rack/oauth2/access_token/authenticator_spec.rb +2 -22
- data/spec/rack/oauth2/access_token/bearer_spec.rb +2 -2
- data/spec/rack/oauth2/access_token_spec.rb +0 -17
- data/spec/rack/oauth2/client_spec.rb +135 -75
- data/spec/rack/oauth2/oauth2_spec.rb +0 -43
- data/spec/rack/oauth2/server/authorize/error_spec.rb +6 -6
- data/spec/rack/oauth2/server/resource/bearer/error_spec.rb +2 -2
- data/spec/rack/oauth2/server/resource/bearer_spec.rb +9 -9
- data/spec/rack/oauth2/server/resource/error_spec.rb +14 -14
- data/spec/rack/oauth2/server/token/authorization_code_spec.rb +2 -2
- data/spec/rack/oauth2/server/token/error_spec.rb +5 -5
- data/spec/rack/oauth2/server/token_spec.rb +71 -2
- metadata +43 -47
- data/.travis.yml +0 -8
- data/lib/rack/oauth2/access_token/legacy.rb +0 -19
- data/lib/rack/oauth2/access_token/mac/sha256_hex_verifier.rb +0 -17
- data/lib/rack/oauth2/access_token/mac/signature.rb +0 -34
- data/lib/rack/oauth2/access_token/mac/verifier.rb +0 -44
- data/lib/rack/oauth2/access_token/mac.rb +0 -103
- data/lib/rack/oauth2/debugger/request_filter.rb +0 -30
- data/lib/rack/oauth2/debugger.rb +0 -3
- data/lib/rack/oauth2/server/resource/mac/error.rb +0 -24
- data/lib/rack/oauth2/server/resource/mac.rb +0 -36
- data/spec/mock_response/tokens/legacy.json +0 -5
- data/spec/mock_response/tokens/legacy.txt +0 -1
- data/spec/mock_response/tokens/legacy_without_expires_in.txt +0 -1
- data/spec/mock_response/tokens/mac.json +0 -8
- data/spec/rack/oauth2/access_token/legacy_spec.rb +0 -23
- data/spec/rack/oauth2/access_token/mac/sha256_hex_verifier_spec.rb +0 -28
- data/spec/rack/oauth2/access_token/mac/signature_spec.rb +0 -59
- data/spec/rack/oauth2/access_token/mac/verifier_spec.rb +0 -25
- data/spec/rack/oauth2/access_token/mac_spec.rb +0 -141
- data/spec/rack/oauth2/debugger/request_filter_spec.rb +0 -33
- data/spec/rack/oauth2/server/resource/mac/error_spec.rb +0 -52
- data/spec/rack/oauth2/server/resource/mac_spec.rb +0 -119
- /data/spec/mock_response/{blank → blank.txt} +0 -0
@@ -7,9 +7,9 @@ describe Rack::OAuth2::Server::Token::BadRequest do
|
|
7
7
|
|
8
8
|
describe '#finish' do
|
9
9
|
it 'should respond in JSON' do
|
10
|
-
status,
|
10
|
+
status, headers, response = error.finish
|
11
11
|
status.should == 400
|
12
|
-
|
12
|
+
headers['Content-Type'].should == 'application/json'
|
13
13
|
response.should == ['{"error":"invalid_request"}']
|
14
14
|
end
|
15
15
|
end
|
@@ -22,10 +22,10 @@ describe Rack::OAuth2::Server::Token::Unauthorized do
|
|
22
22
|
|
23
23
|
describe '#finish' do
|
24
24
|
it 'should respond in JSON' do
|
25
|
-
status,
|
25
|
+
status, headers, response = error.finish
|
26
26
|
status.should == 401
|
27
|
-
|
28
|
-
|
27
|
+
headers['Content-Type'].should == 'application/json'
|
28
|
+
headers['WWW-Authenticate'].should == 'Basic realm="OAuth2 Token Endpoint"'
|
29
29
|
response.should == ['{"error":"invalid_request"}']
|
30
30
|
end
|
31
31
|
end
|
@@ -28,7 +28,7 @@ describe Rack::OAuth2::Server::Token do
|
|
28
28
|
)
|
29
29
|
end
|
30
30
|
it 'should fail with unsupported_grant_type' do
|
31
|
-
status,
|
31
|
+
status, headers, response = app.call(env)
|
32
32
|
status.should == 400
|
33
33
|
response.first.should include '"error":"invalid_request"'
|
34
34
|
end
|
@@ -43,7 +43,7 @@ describe Rack::OAuth2::Server::Token do
|
|
43
43
|
)
|
44
44
|
end
|
45
45
|
it 'should ignore duplicates' do
|
46
|
-
status,
|
46
|
+
status, headers, response = app.call(env)
|
47
47
|
status.should == 200
|
48
48
|
end
|
49
49
|
end
|
@@ -71,6 +71,60 @@ describe Rack::OAuth2::Server::Token do
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
+
context 'when client_id is given via JWT client assertion' do
|
75
|
+
before do
|
76
|
+
require 'json/jwt'
|
77
|
+
params[:client_assertion] = JSON::JWT.new(
|
78
|
+
sub: params[:client_id]
|
79
|
+
# NOTE: actual client_assertion should have more claims.
|
80
|
+
).sign('client_secret').to_s
|
81
|
+
params[:client_assertion_type] = Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER
|
82
|
+
params.delete(:client_id)
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'when client_assertion is invalid JWT' do
|
86
|
+
before do
|
87
|
+
params[:client_assertion] = 'invalid-jwt'
|
88
|
+
end
|
89
|
+
its(:status) { should == 400 }
|
90
|
+
its(:content_type) { should == 'application/json' }
|
91
|
+
its(:body) { should include '"error":"invalid_request"' }
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'when client_assertion_type is missing' do
|
95
|
+
before do
|
96
|
+
params.delete(:client_assertion_type)
|
97
|
+
end
|
98
|
+
its(:status) { should == 400 }
|
99
|
+
its(:content_type) { should == 'application/json' }
|
100
|
+
its(:body) { should include '"error":"invalid_request"' }
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'when client_assertion_type is unknown' do
|
104
|
+
before do
|
105
|
+
params[:client_assertion_type] = 'unknown'
|
106
|
+
end
|
107
|
+
its(:status) { should == 400 }
|
108
|
+
its(:content_type) { should == 'application/json' }
|
109
|
+
its(:body) { should include '"error":"invalid_request"' }
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'when client_assertion issuer is different from client_id' do
|
113
|
+
before do
|
114
|
+
params[:client_id] = 'another_client_id'
|
115
|
+
end
|
116
|
+
its(:status) { should == 400 }
|
117
|
+
its(:content_type) { should == 'application/json' }
|
118
|
+
its(:body) { should include '"error":"invalid_request"' }
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'otherwise' do
|
122
|
+
its(:status) { should == 200 }
|
123
|
+
its(:content_type) { should == 'application/json' }
|
124
|
+
its(:body) { should include '"access_token":"access_token"' }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
74
128
|
Rack::OAuth2::Server::Token::ErrorMethods::DEFAULT_DESCRIPTION.each do |error, default_message|
|
75
129
|
status = if error == :invalid_client
|
76
130
|
401
|
@@ -87,7 +141,22 @@ describe Rack::OAuth2::Server::Token do
|
|
87
141
|
its(:content_type) { should == 'application/json' }
|
88
142
|
its(:body) { should include "\"error\":\"#{error}\"" }
|
89
143
|
its(:body) { should include "\"error_description\":\"#{default_message}\"" }
|
144
|
+
if error == :invalid_client
|
145
|
+
its(:headers) { should include 'WWW-Authenticate' }
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'when skip_www_authenticate option is specified on invalid_client' do
|
151
|
+
let(:app) do
|
152
|
+
Rack::OAuth2::Server::Token.new do |request, response|
|
153
|
+
request.invalid_client!(
|
154
|
+
Rack::OAuth2::Server::Token::ErrorMethods::DEFAULT_DESCRIPTION[:invalid_client],
|
155
|
+
skip_www_authenticate: true
|
156
|
+
)
|
157
|
+
end
|
90
158
|
end
|
159
|
+
its(:headers) { should_not include 'WWW-Authenticate' }
|
91
160
|
end
|
92
161
|
|
93
162
|
context 'when responding' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-oauth2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nov matake
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-12-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -25,7 +25,21 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 2.1.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: faraday
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: faraday-follow_redirects
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
30
44
|
requirements:
|
31
45
|
- - ">="
|
@@ -150,8 +164,21 @@ dependencies:
|
|
150
164
|
- - ">="
|
151
165
|
- !ruby/object:Gem::Version
|
152
166
|
version: '0'
|
153
|
-
|
154
|
-
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rexml
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
description: OAuth 2.0 Server & Client Library. Both Bearer token type are supported.
|
155
182
|
email: nov@matake.jp
|
156
183
|
executables: []
|
157
184
|
extensions: []
|
@@ -160,9 +187,11 @@ extra_rdoc_files:
|
|
160
187
|
- README.rdoc
|
161
188
|
files:
|
162
189
|
- ".document"
|
190
|
+
- ".github/FUNDING.yml"
|
191
|
+
- ".github/workflows/spec.yml"
|
163
192
|
- ".gitignore"
|
164
193
|
- ".rspec"
|
165
|
-
-
|
194
|
+
- CHANGELOG.md
|
166
195
|
- Gemfile
|
167
196
|
- LICENSE
|
168
197
|
- README.rdoc
|
@@ -172,11 +201,6 @@ files:
|
|
172
201
|
- lib/rack/oauth2/access_token.rb
|
173
202
|
- lib/rack/oauth2/access_token/authenticator.rb
|
174
203
|
- lib/rack/oauth2/access_token/bearer.rb
|
175
|
-
- lib/rack/oauth2/access_token/legacy.rb
|
176
|
-
- lib/rack/oauth2/access_token/mac.rb
|
177
|
-
- lib/rack/oauth2/access_token/mac/sha256_hex_verifier.rb
|
178
|
-
- lib/rack/oauth2/access_token/mac/signature.rb
|
179
|
-
- lib/rack/oauth2/access_token/mac/verifier.rb
|
180
204
|
- lib/rack/oauth2/access_token/mtls.rb
|
181
205
|
- lib/rack/oauth2/client.rb
|
182
206
|
- lib/rack/oauth2/client/error.rb
|
@@ -188,8 +212,6 @@ files:
|
|
188
212
|
- lib/rack/oauth2/client/grant/refresh_token.rb
|
189
213
|
- lib/rack/oauth2/client/grant/saml2_bearer.rb
|
190
214
|
- lib/rack/oauth2/client/grant/token_exchange.rb
|
191
|
-
- lib/rack/oauth2/debugger.rb
|
192
|
-
- lib/rack/oauth2/debugger/request_filter.rb
|
193
215
|
- lib/rack/oauth2/server.rb
|
194
216
|
- lib/rack/oauth2/server/abstract.rb
|
195
217
|
- lib/rack/oauth2/server/abstract/error.rb
|
@@ -212,8 +234,6 @@ files:
|
|
212
234
|
- lib/rack/oauth2/server/resource/bearer.rb
|
213
235
|
- lib/rack/oauth2/server/resource/bearer/error.rb
|
214
236
|
- lib/rack/oauth2/server/resource/error.rb
|
215
|
-
- lib/rack/oauth2/server/resource/mac.rb
|
216
|
-
- lib/rack/oauth2/server/resource/mac/error.rb
|
217
237
|
- lib/rack/oauth2/server/token.rb
|
218
238
|
- lib/rack/oauth2/server/token/authorization_code.rb
|
219
239
|
- lib/rack/oauth2/server/token/client_credentials.rb
|
@@ -229,23 +249,14 @@ files:
|
|
229
249
|
- rack-oauth2.gemspec
|
230
250
|
- spec/helpers/time.rb
|
231
251
|
- spec/helpers/webmock_helper.rb
|
232
|
-
- spec/mock_response/blank
|
252
|
+
- spec/mock_response/blank.txt
|
233
253
|
- spec/mock_response/errors/invalid_request.json
|
234
254
|
- spec/mock_response/resources/fake.txt
|
235
255
|
- spec/mock_response/tokens/_Bearer.json
|
236
256
|
- spec/mock_response/tokens/bearer.json
|
237
|
-
- spec/mock_response/tokens/legacy.json
|
238
|
-
- spec/mock_response/tokens/legacy.txt
|
239
|
-
- spec/mock_response/tokens/legacy_without_expires_in.txt
|
240
|
-
- spec/mock_response/tokens/mac.json
|
241
257
|
- spec/mock_response/tokens/unknown.json
|
242
258
|
- spec/rack/oauth2/access_token/authenticator_spec.rb
|
243
259
|
- spec/rack/oauth2/access_token/bearer_spec.rb
|
244
|
-
- spec/rack/oauth2/access_token/legacy_spec.rb
|
245
|
-
- spec/rack/oauth2/access_token/mac/sha256_hex_verifier_spec.rb
|
246
|
-
- spec/rack/oauth2/access_token/mac/signature_spec.rb
|
247
|
-
- spec/rack/oauth2/access_token/mac/verifier_spec.rb
|
248
|
-
- spec/rack/oauth2/access_token/mac_spec.rb
|
249
260
|
- spec/rack/oauth2/access_token_spec.rb
|
250
261
|
- spec/rack/oauth2/client/error_spec.rb
|
251
262
|
- spec/rack/oauth2/client/grant/authorization_code_spec.rb
|
@@ -255,7 +266,6 @@ files:
|
|
255
266
|
- spec/rack/oauth2/client/grant/refresh_token_spec.rb
|
256
267
|
- spec/rack/oauth2/client/grant/saml2_bearer_spec.rb
|
257
268
|
- spec/rack/oauth2/client_spec.rb
|
258
|
-
- spec/rack/oauth2/debugger/request_filter_spec.rb
|
259
269
|
- spec/rack/oauth2/oauth2_spec.rb
|
260
270
|
- spec/rack/oauth2/server/abstract/error_spec.rb
|
261
271
|
- spec/rack/oauth2/server/authorize/code_spec.rb
|
@@ -268,8 +278,6 @@ files:
|
|
268
278
|
- spec/rack/oauth2/server/resource/bearer/error_spec.rb
|
269
279
|
- spec/rack/oauth2/server/resource/bearer_spec.rb
|
270
280
|
- spec/rack/oauth2/server/resource/error_spec.rb
|
271
|
-
- spec/rack/oauth2/server/resource/mac/error_spec.rb
|
272
|
-
- spec/rack/oauth2/server/resource/mac_spec.rb
|
273
281
|
- spec/rack/oauth2/server/resource_spec.rb
|
274
282
|
- spec/rack/oauth2/server/token/authorization_code_spec.rb
|
275
283
|
- spec/rack/oauth2/server/token/client_credentials_spec.rb
|
@@ -281,11 +289,11 @@ files:
|
|
281
289
|
- spec/rack/oauth2/server/token_spec.rb
|
282
290
|
- spec/rack/oauth2/util_spec.rb
|
283
291
|
- spec/spec_helper.rb
|
284
|
-
homepage:
|
292
|
+
homepage: https://github.com/nov/rack-oauth2
|
285
293
|
licenses:
|
286
294
|
- MIT
|
287
295
|
metadata: {}
|
288
|
-
post_install_message:
|
296
|
+
post_install_message:
|
289
297
|
rdoc_options:
|
290
298
|
- "--charset=UTF-8"
|
291
299
|
require_paths:
|
@@ -301,30 +309,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
301
309
|
- !ruby/object:Gem::Version
|
302
310
|
version: '0'
|
303
311
|
requirements: []
|
304
|
-
rubygems_version: 3.
|
305
|
-
signing_key:
|
312
|
+
rubygems_version: 3.4.10
|
313
|
+
signing_key:
|
306
314
|
specification_version: 4
|
307
|
-
summary: OAuth 2.0 Server & Client Library - Both Bearer
|
315
|
+
summary: OAuth 2.0 Server & Client Library - Both Bearer token type are supported
|
308
316
|
test_files:
|
309
317
|
- spec/helpers/time.rb
|
310
318
|
- spec/helpers/webmock_helper.rb
|
311
|
-
- spec/mock_response/blank
|
319
|
+
- spec/mock_response/blank.txt
|
312
320
|
- spec/mock_response/errors/invalid_request.json
|
313
321
|
- spec/mock_response/resources/fake.txt
|
314
322
|
- spec/mock_response/tokens/_Bearer.json
|
315
323
|
- spec/mock_response/tokens/bearer.json
|
316
|
-
- spec/mock_response/tokens/legacy.json
|
317
|
-
- spec/mock_response/tokens/legacy.txt
|
318
|
-
- spec/mock_response/tokens/legacy_without_expires_in.txt
|
319
|
-
- spec/mock_response/tokens/mac.json
|
320
324
|
- spec/mock_response/tokens/unknown.json
|
321
325
|
- spec/rack/oauth2/access_token/authenticator_spec.rb
|
322
326
|
- spec/rack/oauth2/access_token/bearer_spec.rb
|
323
|
-
- spec/rack/oauth2/access_token/legacy_spec.rb
|
324
|
-
- spec/rack/oauth2/access_token/mac/sha256_hex_verifier_spec.rb
|
325
|
-
- spec/rack/oauth2/access_token/mac/signature_spec.rb
|
326
|
-
- spec/rack/oauth2/access_token/mac/verifier_spec.rb
|
327
|
-
- spec/rack/oauth2/access_token/mac_spec.rb
|
328
327
|
- spec/rack/oauth2/access_token_spec.rb
|
329
328
|
- spec/rack/oauth2/client/error_spec.rb
|
330
329
|
- spec/rack/oauth2/client/grant/authorization_code_spec.rb
|
@@ -334,7 +333,6 @@ test_files:
|
|
334
333
|
- spec/rack/oauth2/client/grant/refresh_token_spec.rb
|
335
334
|
- spec/rack/oauth2/client/grant/saml2_bearer_spec.rb
|
336
335
|
- spec/rack/oauth2/client_spec.rb
|
337
|
-
- spec/rack/oauth2/debugger/request_filter_spec.rb
|
338
336
|
- spec/rack/oauth2/oauth2_spec.rb
|
339
337
|
- spec/rack/oauth2/server/abstract/error_spec.rb
|
340
338
|
- spec/rack/oauth2/server/authorize/code_spec.rb
|
@@ -347,8 +345,6 @@ test_files:
|
|
347
345
|
- spec/rack/oauth2/server/resource/bearer/error_spec.rb
|
348
346
|
- spec/rack/oauth2/server/resource/bearer_spec.rb
|
349
347
|
- spec/rack/oauth2/server/resource/error_spec.rb
|
350
|
-
- spec/rack/oauth2/server/resource/mac/error_spec.rb
|
351
|
-
- spec/rack/oauth2/server/resource/mac_spec.rb
|
352
348
|
- spec/rack/oauth2/server/resource_spec.rb
|
353
349
|
- spec/rack/oauth2/server/token/authorization_code_spec.rb
|
354
350
|
- spec/rack/oauth2/server/token/client_credentials_spec.rb
|
data/.travis.yml
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
module Rack
|
2
|
-
module OAuth2
|
3
|
-
class AccessToken
|
4
|
-
class Legacy < AccessToken
|
5
|
-
def initialize(attributes = {})
|
6
|
-
super
|
7
|
-
self.expires_in = (
|
8
|
-
self.expires_in ||
|
9
|
-
attributes[:expires]
|
10
|
-
).try(:to_i)
|
11
|
-
end
|
12
|
-
|
13
|
-
def authenticate(request)
|
14
|
-
request.header["Authorization"] = "OAuth #{access_token}"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Rack
|
2
|
-
module OAuth2
|
3
|
-
class AccessToken
|
4
|
-
class MAC
|
5
|
-
class Sha256HexVerifier < Verifier
|
6
|
-
attr_optional :raw_body
|
7
|
-
|
8
|
-
def calculate
|
9
|
-
return nil unless raw_body.present?
|
10
|
-
|
11
|
-
OpenSSL::Digest::SHA256.new.digest(raw_body).unpack('H*').first
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module Rack
|
2
|
-
module OAuth2
|
3
|
-
class AccessToken
|
4
|
-
class MAC
|
5
|
-
class Signature < Verifier
|
6
|
-
attr_required :secret, :ts, :nonce, :method, :request_uri, :host, :port
|
7
|
-
attr_optional :ext, :query
|
8
|
-
|
9
|
-
def calculate
|
10
|
-
Rack::OAuth2::Util.base64_encode OpenSSL::HMAC.digest(
|
11
|
-
hash_generator,
|
12
|
-
secret,
|
13
|
-
normalized_request_string
|
14
|
-
)
|
15
|
-
end
|
16
|
-
|
17
|
-
def normalized_request_string
|
18
|
-
[
|
19
|
-
ts.to_i,
|
20
|
-
nonce,
|
21
|
-
method.to_s.upcase,
|
22
|
-
request_uri,
|
23
|
-
host,
|
24
|
-
port,
|
25
|
-
ext || '',
|
26
|
-
nil
|
27
|
-
].join("\n")
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
module Rack
|
2
|
-
module OAuth2
|
3
|
-
class AccessToken
|
4
|
-
class MAC
|
5
|
-
class Verifier
|
6
|
-
include AttrRequired, AttrOptional
|
7
|
-
attr_required :algorithm
|
8
|
-
|
9
|
-
class VerificationFailed < StandardError; end
|
10
|
-
|
11
|
-
def initialize(attributes = {})
|
12
|
-
(required_attributes + optional_attributes).each do |key|
|
13
|
-
self.send :"#{key}=", attributes[key]
|
14
|
-
end
|
15
|
-
attr_missing!
|
16
|
-
rescue AttrRequired::AttrMissing => e
|
17
|
-
raise VerificationFailed.new("#{self.class.name.demodulize} Invalid: #{e.message}")
|
18
|
-
end
|
19
|
-
|
20
|
-
def verify!(expected)
|
21
|
-
if expected == self.calculate
|
22
|
-
:verified
|
23
|
-
else
|
24
|
-
raise VerificationFailed.new("#{self.class.name.demodulize} Invalid")
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def hash_generator
|
31
|
-
case algorithm.to_s
|
32
|
-
when 'hmac-sha-1'
|
33
|
-
OpenSSL::Digest::SHA1.new
|
34
|
-
when 'hmac-sha-256'
|
35
|
-
OpenSSL::Digest::SHA256.new
|
36
|
-
else
|
37
|
-
raise 'Unsupported Algorithm'
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,103 +0,0 @@
|
|
1
|
-
module Rack
|
2
|
-
module OAuth2
|
3
|
-
class AccessToken
|
4
|
-
class MAC < AccessToken
|
5
|
-
attr_required :mac_key, :mac_algorithm
|
6
|
-
attr_optional :ts, :ext_verifier, :ts_expires_in
|
7
|
-
attr_reader :nonce, :signature, :ext
|
8
|
-
|
9
|
-
def initialize(attributes = {})
|
10
|
-
super(attributes)
|
11
|
-
@issued_at = Time.now.utc
|
12
|
-
@ts_expires_in ||= 5.minutes
|
13
|
-
end
|
14
|
-
|
15
|
-
def token_response
|
16
|
-
super.merge(
|
17
|
-
mac_key: mac_key,
|
18
|
-
mac_algorithm: mac_algorithm
|
19
|
-
)
|
20
|
-
end
|
21
|
-
|
22
|
-
def verify!(request)
|
23
|
-
if self.ext_verifier.present?
|
24
|
-
body = request.body.read
|
25
|
-
request.body.rewind # for future use
|
26
|
-
|
27
|
-
self.ext_verifier.new(
|
28
|
-
raw_body: body,
|
29
|
-
algorithm: self.mac_algorithm
|
30
|
-
).verify!(request.ext)
|
31
|
-
end
|
32
|
-
|
33
|
-
now = Time.now.utc.to_i
|
34
|
-
now = @ts.to_i if @ts.present?
|
35
|
-
|
36
|
-
raise Rack::OAuth2::AccessToken::MAC::Verifier::VerificationFailed.new("Request ts expired") if now - request.ts.to_i > @ts_expires_in.to_i
|
37
|
-
|
38
|
-
Signature.new(
|
39
|
-
secret: self.mac_key,
|
40
|
-
algorithm: self.mac_algorithm,
|
41
|
-
nonce: request.nonce,
|
42
|
-
method: request.request_method,
|
43
|
-
request_uri: request.fullpath,
|
44
|
-
host: request.host,
|
45
|
-
port: request.port,
|
46
|
-
ts: request.ts,
|
47
|
-
ext: request.ext
|
48
|
-
).verify!(request.signature)
|
49
|
-
rescue Verifier::VerificationFailed => e
|
50
|
-
request.invalid_token! e.message
|
51
|
-
end
|
52
|
-
|
53
|
-
def authenticate(request)
|
54
|
-
@nonce = generate_nonce
|
55
|
-
@ts_generated = @ts || Time.now.utc
|
56
|
-
|
57
|
-
if self.ext_verifier.present?
|
58
|
-
@ext = self.ext_verifier.new(
|
59
|
-
raw_body: request.body,
|
60
|
-
algorithm: self.mac_algorithm
|
61
|
-
).calculate
|
62
|
-
end
|
63
|
-
|
64
|
-
@signature = Signature.new(
|
65
|
-
secret: self.mac_key,
|
66
|
-
algorithm: self.mac_algorithm,
|
67
|
-
nonce: self.nonce,
|
68
|
-
method: request.header.request_method,
|
69
|
-
request_uri: request.header.create_query_uri,
|
70
|
-
host: request.header.request_uri.host,
|
71
|
-
port: request.header.request_uri.port,
|
72
|
-
ts: @ts_generated,
|
73
|
-
ext: @ext
|
74
|
-
).calculate
|
75
|
-
|
76
|
-
request.header['Authorization'] = authorization_header
|
77
|
-
end
|
78
|
-
|
79
|
-
private
|
80
|
-
|
81
|
-
def authorization_header
|
82
|
-
header = "MAC id=\"#{access_token}\""
|
83
|
-
header << ", nonce=\"#{nonce}\""
|
84
|
-
header << ", ts=\"#{@ts_generated.to_i}\""
|
85
|
-
header << ", mac=\"#{signature}\""
|
86
|
-
header << ", ext=\"#{ext}\"" if @ext.present?
|
87
|
-
header
|
88
|
-
end
|
89
|
-
|
90
|
-
def generate_nonce
|
91
|
-
[
|
92
|
-
(Time.now.utc - @issued_at).to_i,
|
93
|
-
SecureRandom.hex
|
94
|
-
].join(':')
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
require 'rack/oauth2/access_token/mac/verifier'
|
102
|
-
require 'rack/oauth2/access_token/mac/sha256_hex_verifier'
|
103
|
-
require 'rack/oauth2/access_token/mac/signature'
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module Rack
|
2
|
-
module OAuth2
|
3
|
-
module Debugger
|
4
|
-
class RequestFilter
|
5
|
-
# Callback called in HTTPClient (before sending a request)
|
6
|
-
# request:: HTTP::Message
|
7
|
-
def filter_request(request)
|
8
|
-
started = "======= [Rack::OAuth2] HTTP REQUEST STARTED ======="
|
9
|
-
log started, request.dump
|
10
|
-
end
|
11
|
-
|
12
|
-
# Callback called in HTTPClient (after received a response)
|
13
|
-
# request:: HTTP::Message
|
14
|
-
# response:: HTTP::Message
|
15
|
-
def filter_response(request, response)
|
16
|
-
finished = "======= [Rack::OAuth2] HTTP REQUEST FINISHED ======="
|
17
|
-
log '-' * 50, response.dump, finished
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def log(*outputs)
|
23
|
-
outputs.each do |output|
|
24
|
-
OAuth2.logger.info output
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
data/lib/rack/oauth2/debugger.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
module Rack
|
2
|
-
module OAuth2
|
3
|
-
module Server
|
4
|
-
class Resource
|
5
|
-
class MAC
|
6
|
-
class Unauthorized < Resource::Unauthorized
|
7
|
-
def scheme
|
8
|
-
:MAC
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
module ErrorMethods
|
13
|
-
include Resource::ErrorMethods
|
14
|
-
def unauthorized!(error = nil, description = nil, options = {})
|
15
|
-
raise Unauthorized.new(error, description, options)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
Request.send :include, ErrorMethods
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module Rack
|
2
|
-
module OAuth2
|
3
|
-
module Server
|
4
|
-
class Resource
|
5
|
-
class MAC < Resource
|
6
|
-
def _call(env)
|
7
|
-
self.request = Request.new(env)
|
8
|
-
super
|
9
|
-
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
class Request < Resource::Request
|
14
|
-
attr_reader :nonce, :ts, :ext, :signature
|
15
|
-
|
16
|
-
def setup!
|
17
|
-
auth_params = Rack::Auth::Digest::Params.parse(@auth_header.params).with_indifferent_access
|
18
|
-
@access_token = auth_params[:id]
|
19
|
-
@nonce = auth_params[:nonce]
|
20
|
-
@ts = auth_params[:ts]
|
21
|
-
@ext = auth_params[:ext]
|
22
|
-
@signature = auth_params[:mac]
|
23
|
-
self
|
24
|
-
end
|
25
|
-
|
26
|
-
def oauth2?
|
27
|
-
@auth_header.provided? && @auth_header.scheme.to_s == 'mac'
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
require 'rack/oauth2/server/resource/mac/error'
|
@@ -1 +0,0 @@
|
|
1
|
-
access_token=access_token&expires=3600
|
@@ -1 +0,0 @@
|
|
1
|
-
access_token=access_token
|