rack-oauth2 1.21.3 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/spec.yml +6 -5
  3. data/CHANGELOG.md +31 -0
  4. data/README.rdoc +1 -20
  5. data/VERSION +1 -1
  6. data/lib/rack/oauth2/access_token/authenticator.rb +1 -10
  7. data/lib/rack/oauth2/access_token/bearer.rb +1 -1
  8. data/lib/rack/oauth2/access_token/mtls.rb +2 -2
  9. data/lib/rack/oauth2/access_token.rb +4 -6
  10. data/lib/rack/oauth2/client.rb +13 -16
  11. data/lib/rack/oauth2/server/extension/pkce.rb +1 -1
  12. data/lib/rack/oauth2/server/resource.rb +0 -1
  13. data/lib/rack/oauth2.rb +11 -15
  14. data/rack-oauth2.gemspec +4 -3
  15. data/spec/helpers/webmock_helper.rb +8 -2
  16. data/spec/rack/oauth2/access_token/authenticator_spec.rb +2 -22
  17. data/spec/rack/oauth2/access_token/bearer_spec.rb +2 -2
  18. data/spec/rack/oauth2/access_token_spec.rb +0 -17
  19. data/spec/rack/oauth2/client_spec.rb +58 -80
  20. data/spec/rack/oauth2/oauth2_spec.rb +0 -43
  21. metadata +23 -43
  22. data/.travis.yml +0 -8
  23. data/lib/rack/oauth2/access_token/legacy.rb +0 -19
  24. data/lib/rack/oauth2/access_token/mac/sha256_hex_verifier.rb +0 -17
  25. data/lib/rack/oauth2/access_token/mac/signature.rb +0 -34
  26. data/lib/rack/oauth2/access_token/mac/verifier.rb +0 -44
  27. data/lib/rack/oauth2/access_token/mac.rb +0 -103
  28. data/lib/rack/oauth2/debugger/request_filter.rb +0 -30
  29. data/lib/rack/oauth2/debugger.rb +0 -3
  30. data/lib/rack/oauth2/server/resource/mac/error.rb +0 -24
  31. data/lib/rack/oauth2/server/resource/mac.rb +0 -36
  32. data/spec/mock_response/tokens/legacy.json +0 -5
  33. data/spec/mock_response/tokens/legacy.txt +0 -1
  34. data/spec/mock_response/tokens/legacy_without_expires_in.txt +0 -1
  35. data/spec/mock_response/tokens/mac.json +0 -8
  36. data/spec/rack/oauth2/access_token/legacy_spec.rb +0 -23
  37. data/spec/rack/oauth2/access_token/mac/sha256_hex_verifier_spec.rb +0 -28
  38. data/spec/rack/oauth2/access_token/mac/signature_spec.rb +0 -59
  39. data/spec/rack/oauth2/access_token/mac/verifier_spec.rb +0 -25
  40. data/spec/rack/oauth2/access_token/mac_spec.rb +0 -141
  41. data/spec/rack/oauth2/debugger/request_filter_spec.rb +0 -33
  42. data/spec/rack/oauth2/server/resource/mac/error_spec.rb +0 -52
  43. data/spec/rack/oauth2/server/resource/mac_spec.rb +0 -119
  44. /data/spec/mock_response/{blank → blank.txt} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7303cf85e66a7fb4a89d66d95b4ad35720ecb95459f9740208328314ea54b157
4
- data.tar.gz: 061a4a30cbb25212979a37f26e18043cbf71dead3e36981b37f6152fc6899cfd
3
+ metadata.gz: f2c3515e2af90285deab9032fece3d0ef8c7445405cc1cce705160c19fb2052b
4
+ data.tar.gz: e95c0fca744d8d12d97e1be23ff48cb00250d92a536de03382021e73e809c737
5
5
  SHA512:
6
- metadata.gz: 5fbabf81d770e80f02614d3b00b0fd9db8a63ed695a5b67b74266eee1f09ec6e7045db009ea7e6ee09af84680699809032ecc64d58caee48305573cd3532b5be
7
- data.tar.gz: 5bc8cdbdddb9a997560eab574a955ab69d3ad8f9e594554a45d17e077991c2551382c917363c1c09db349abf262f5d9c15a7cfb13c24e56fe27d83cbde62f0f3
6
+ metadata.gz: 6c2a9ddb2f9b4b9d18c337d678bf88d660f3597d09ec9d63195062cd1c5fc0a3c5105135f51aa1f4efef4e64b9e66c2a6f36dc6b4037b5c09cefbace858ce67e
7
+ data.tar.gz: e0add9d0227669a3cfd6e11c208bc36f89c13ec8cda2ab2352bb9b0d29ee0ac59b266aee90732c4e756895fc8d66ebaefdd4defe5342392e67e08d9022514da9
@@ -2,6 +2,8 @@ name: Spec
2
2
 
3
3
  on:
4
4
  push:
5
+ branches:
6
+ - main
5
7
  pull_request:
6
8
 
7
9
  permissions:
@@ -11,12 +13,11 @@ jobs:
11
13
  spec:
12
14
  strategy:
13
15
  matrix:
14
- os: ['ubuntu-20.04']
15
- ruby-version: ['2.6', '2.7', '3.0', '3.1']
16
- # ubuntu 22.04 only supports ssl 3 and thus only ruby 3.1
16
+ os: ['ubuntu-20.04', 'ubuntu-22.04']
17
+ ruby-version: ['3.1', '3.2', '3.3']
17
18
  include:
18
- - os: 'ubuntu-22.04'
19
- ruby-version: '3.1'
19
+ - os: 'ubuntu-20.04'
20
+ ruby-version: '3.0'
20
21
  runs-on: ${{ matrix.os }}
21
22
 
22
23
  steps:
data/CHANGELOG.md ADDED
@@ -0,0 +1,31 @@
1
+ ## [Unreleased]
2
+
3
+ ## [2.2.0] - 2022-10-11
4
+
5
+ ### Changed
6
+
7
+ - automatic json response decoding, and remove legacy token support by @nov in https://github.com/nov/rack-oauth2/pull/95
8
+
9
+ ## [2.1.0] - 2022-10-10
10
+
11
+ ### Added
12
+
13
+ - accept local_http_config on Rack::OAuth2::Client#access_token! & revoke! to support custom headers etc. by @nov in https://github.com/nov/rack-oauth2/pull/93
14
+
15
+ ## [2.0.1] - 2022-10-09
16
+
17
+ ### Fixed
18
+
19
+ - changes for mTLS on faraday by @nov in https://github.com/nov/rack-oauth2/pull/92
20
+
21
+ ## [2.0.0] - 2022-10-09
22
+
23
+ ### Added
24
+
25
+ - start recording CHANGELOG
26
+
27
+ ### Changed
28
+
29
+ - Switch from httpclient to faraday v2 https://github.com/nov/rack-oauth2/pull/91
30
+ - make url-encoded the default https://github.com/nov/rack-oauth2/commit/98faf139be4f5bf9ec6134d31f65a298259d8a8b
31
+ - let faraday encode params https://github.com/nov/rack-oauth2/commit/f399b3afb8facb3635b8842baee8584bc4d3ce73
data/README.rdoc CHANGED
@@ -1,9 +1,7 @@
1
1
  = rack-oauth2
2
2
 
3
3
  OAuth 2.0 Server & Client Library.
4
- Both Bearer and MAC token type are supported.
5
-
6
- {<img src="https://secure.travis-ci.org/nov/rack-oauth2.png" />}[http://travis-ci.org/nov/rack-oauth2]
4
+ Both Bearer token type are supported.
7
5
 
8
6
  The OAuth 2.0 Authorization Framework (RFC 6749)
9
7
  http://www.rfc-editor.org/rfc/rfc6749.txt
@@ -11,9 +9,6 @@ http://www.rfc-editor.org/rfc/rfc6749.txt
11
9
  The OAuth 2.0 Authorization Framework: Bearer Token Usage (RFC 6750)
12
10
  http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-06
13
11
 
14
- HTTP Authentication: MAC Access Authentication (draft 01)
15
- http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01
16
-
17
12
  == Installation
18
13
 
19
14
  gem install rack-oauth2
@@ -31,31 +26,17 @@ http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01
31
26
  Source on GitHub
32
27
  https://github.com/nov/rack-oauth2-sample
33
28
 
34
- === MAC
35
-
36
- Source on GitHub
37
- https://github.com/nov/rack-oauth2-sample-mac
38
-
39
29
  == Sample Client
40
30
 
41
- === Common between Bearer and MAC
42
-
43
31
  Authorization Request (request_type: 'code' and 'token')
44
32
  https://gist.github.com/862393
45
33
 
46
34
  Token Request (grant_type: 'client_credentials', 'password', 'authorization_code' and 'refresh_token')
47
35
  https://gist.github.com/883541
48
36
 
49
- === Bearer
50
-
51
37
  Resource Request (request both for resource owner resource and for client resource)
52
38
  https://gist.github.com/883575
53
39
 
54
- === MAC
55
-
56
- Resource Request (request both for resource owner resource and for client resource)
57
- https://gist.github.com/933885
58
-
59
40
  == Note on Patches/Pull Requests
60
41
 
61
42
  * Fork the project.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.21.3
1
+ 2.2.1
@@ -6,18 +6,9 @@ module Rack
6
6
  @token = token
7
7
  end
8
8
 
9
- # Callback called in HTTPClient (before sending a request)
10
- # request:: HTTP::Message
11
- def filter_request(request)
9
+ def authenticate(request)
12
10
  @token.authenticate(request)
13
11
  end
14
-
15
- # Callback called in HTTPClient (after received a response)
16
- # response:: HTTP::Message
17
- # request:: HTTP::Message
18
- def filter_response(response, request)
19
- # nothing to do
20
- end
21
12
  end
22
13
  end
23
14
  end
@@ -3,7 +3,7 @@ module Rack
3
3
  class AccessToken
4
4
  class Bearer < AccessToken
5
5
  def authenticate(request)
6
- request.header["Authorization"] = "Bearer #{access_token}"
6
+ request.headers["Authorization"] = "Bearer #{access_token}"
7
7
  end
8
8
 
9
9
  def to_mtls(attributes = {})
@@ -7,8 +7,8 @@ module Rack
7
7
  def initialize(attributes = {})
8
8
  super
9
9
  self.token_type = :bearer
10
- httpclient.ssl_config.client_key = private_key
11
- httpclient.ssl_config.client_cert = certificate
10
+ http_client.ssl.client_key = private_key
11
+ http_client.ssl.client_cert = certificate
12
12
  end
13
13
  end
14
14
  end
@@ -5,7 +5,7 @@ module Rack
5
5
  attr_required :access_token, :token_type
6
6
  attr_optional :refresh_token, :expires_in, :scope
7
7
  attr_accessor :raw_attributes
8
- delegate :get, :patch, :post, :put, :delete, to: :httpclient
8
+ delegate :get, :patch, :post, :put, :delete, to: :http_client
9
9
 
10
10
  alias_method :to_s, :access_token
11
11
 
@@ -18,9 +18,9 @@ module Rack
18
18
  attr_missing!
19
19
  end
20
20
 
21
- def httpclient
22
- @httpclient ||= Rack::OAuth2.http_client("#{self.class} (#{VERSION})") do |config|
23
- config.request_filter << Authenticator.new(self)
21
+ def http_client
22
+ @http_client ||= Rack::OAuth2.http_client("#{self.class} (#{VERSION})") do |faraday|
23
+ Authenticator.new(self).authenticate(faraday)
24
24
  end
25
25
  end
26
26
 
@@ -39,6 +39,4 @@ end
39
39
 
40
40
  require 'rack/oauth2/access_token/authenticator'
41
41
  require 'rack/oauth2/access_token/bearer'
42
- require 'rack/oauth2/access_token/mac'
43
- require 'rack/oauth2/access_token/legacy'
44
42
  require 'rack/oauth2/access_token/mtls'
@@ -78,7 +78,9 @@ module Rack
78
78
  absolute_uri_for(token_endpoint),
79
79
  Util.compact_hash(params),
80
80
  headers
81
- )
81
+ ) do |req|
82
+ yield req if block_given?
83
+ end
82
84
  end
83
85
  end
84
86
 
@@ -111,7 +113,9 @@ module Rack
111
113
  absolute_uri_for(revocation_endpoint),
112
114
  Util.compact_hash(params),
113
115
  headers
114
- )
116
+ ) do |req|
117
+ yield req if block_given?
118
+ end
115
119
  end
116
120
  end
117
121
 
@@ -134,7 +138,7 @@ module Rack
134
138
  # Using Array#extract_options! for backward compatibility.
135
139
  # Until v1.0.5, the first argument was 'client_auth_method' in scalar.
136
140
  options = args.extract_options!
137
- client_auth_method = args.first || options.delete(:client_auth_method).try(:to_sym) || :basic
141
+ client_auth_method = args.first || options.delete(:client_auth_method)&.to_sym || :basic
138
142
 
139
143
  case client_auth_method
140
144
  when :basic
@@ -176,8 +180,8 @@ module Rack
176
180
  params.merge!(
177
181
  client_id: identifier
178
182
  )
179
- http_client.ssl_config.client_key = private_key
180
- http_client.ssl_config.client_cert = certificate
183
+ http_client.ssl.client_key = private_key
184
+ http_client.ssl.client_cert = certificate
181
185
  else
182
186
  params.merge!(
183
187
  client_id: identifier,
@@ -209,26 +213,19 @@ module Rack
209
213
  end
210
214
 
211
215
  def handle_success_response(response)
212
- token_hash = JSON.parse(response.body).with_indifferent_access
213
- case (@forced_token_type || token_hash[:token_type]).try(:downcase)
216
+ token_hash = response.body.with_indifferent_access
217
+ case (@forced_token_type || token_hash[:token_type])&.downcase
214
218
  when 'bearer'
215
219
  AccessToken::Bearer.new(token_hash)
216
- when 'mac'
217
- AccessToken::MAC.new(token_hash)
218
- when nil
219
- AccessToken::Legacy.new(token_hash)
220
220
  else
221
221
  raise 'Unknown Token Type'
222
222
  end
223
- rescue JSON::ParserError
224
- # NOTE: Facebook support (They don't use JSON as token response)
225
- AccessToken::Legacy.new Rack::Utils.parse_nested_query(response.body).with_indifferent_access
226
223
  end
227
224
 
228
225
  def handle_error_response(response)
229
- error = JSON.parse(response.body).with_indifferent_access
226
+ error = response.body.with_indifferent_access
230
227
  raise Error.new(response.status, error)
231
- rescue JSON::ParserError
228
+ rescue Faraday::ParsingError, NoMethodError
232
229
  raise Error.new(response.status, error: 'Unknown', error_description: response.body)
233
230
  end
234
231
  end
@@ -27,7 +27,7 @@ module Rack
27
27
 
28
28
  def verify_code_verifier!(code_challenge, code_challenge_method = :S256)
29
29
  if code_verifier.present? || code_challenge.present?
30
- case code_challenge_method.try(:to_sym)
30
+ case code_challenge_method&.to_sym
31
31
  when :S256
32
32
  code_challenge == Util.urlsafe_base64_encode(
33
33
  OpenSSL::Digest::SHA256.digest(code_verifier.to_s)
@@ -52,4 +52,3 @@ end
52
52
 
53
53
  require 'rack/oauth2/server/resource/error'
54
54
  require 'rack/oauth2/server/resource/bearer'
55
- require 'rack/oauth2/server/resource/mac'
data/lib/rack/oauth2.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'rack'
2
- require 'httpclient'
2
+ require 'faraday'
3
+ require 'faraday/follow_redirects'
3
4
  require 'logger'
4
5
  require 'active_support'
5
6
  require 'active_support/core_ext'
@@ -40,18 +41,15 @@ module Rack
40
41
  self.debugging = false
41
42
 
42
43
  def self.http_client(agent_name = "Rack::OAuth2 (#{VERSION})", &local_http_config)
43
- _http_client_ = HTTPClient.new(
44
- agent_name: agent_name
45
- )
46
-
47
- # NOTE: httpclient gem seems stopped maintaining root certtificate set, use OS default.
48
- _http_client_.ssl_config.clear_cert_store
49
- _http_client_.ssl_config.cert_store.set_default_paths
50
-
51
- http_config.try(:call, _http_client_)
52
- local_http_config.try(:call, _http_client_) unless local_http_config.nil?
53
- _http_client_.request_filter << Debugger::RequestFilter.new if debugging?
54
- _http_client_
44
+ Faraday.new(headers: {user_agent: agent_name}) do |faraday|
45
+ faraday.request :url_encoded
46
+ faraday.request :json
47
+ faraday.response :json
48
+ faraday.adapter Faraday.default_adapter
49
+ local_http_config&.call(faraday)
50
+ http_config&.call(faraday)
51
+ faraday.response :logger, Rack::OAuth2.logger, bodies: true if debugging?
52
+ end
55
53
  end
56
54
 
57
55
  def self.http_config(&block)
@@ -61,7 +59,6 @@ module Rack
61
59
  def self.reset_http_config!
62
60
  @@http_config = nil
63
61
  end
64
-
65
62
  end
66
63
  end
67
64
 
@@ -70,4 +67,3 @@ require 'rack/oauth2/util'
70
67
  require 'rack/oauth2/server'
71
68
  require 'rack/oauth2/client'
72
69
  require 'rack/oauth2/access_token'
73
- require 'rack/oauth2/debugger'
data/rack-oauth2.gemspec CHANGED
@@ -2,8 +2,8 @@ Gem::Specification.new do |s|
2
2
  s.name = 'rack-oauth2'
3
3
  s.version = File.read('VERSION')
4
4
  s.authors = ['nov matake']
5
- s.description = %q{OAuth 2.0 Server & Client Library. Both Bearer and MAC token type are supported.}
6
- s.summary = %q{OAuth 2.0 Server & Client Library - Both Bearer and MAC token type are supported}
5
+ s.description = %q{OAuth 2.0 Server & Client Library. Both Bearer token type are supported.}
6
+ s.summary = %q{OAuth 2.0 Server & Client Library - Both Bearer token type are supported}
7
7
  s.email = 'nov@matake.jp'
8
8
  s.extra_rdoc_files = ['LICENSE', 'README.rdoc']
9
9
  s.rdoc_options = ['--charset=UTF-8']
@@ -14,7 +14,8 @@ Gem::Specification.new do |s|
14
14
  s.files = `git ls-files`.split("\n")
15
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
16
  s.add_runtime_dependency 'rack', '>= 2.1.0'
17
- s.add_runtime_dependency 'httpclient'
17
+ s.add_runtime_dependency 'faraday', '~> 2.0'
18
+ s.add_runtime_dependency 'faraday-follow_redirects'
18
19
  s.add_runtime_dependency 'activesupport'
19
20
  s.add_runtime_dependency 'attr_required'
20
21
  s.add_runtime_dependency 'json-jwt', '>= 1.11.0'
@@ -13,7 +13,7 @@ module WebMockHelper
13
13
 
14
14
  def request_for(method, options = {})
15
15
  request = {}
16
- params = options.try(:[], :params) || {}
16
+ params = options&.[](:params) || {}
17
17
  case method
18
18
  when :post, :put, :delete
19
19
  request[:body] = params
@@ -28,7 +28,13 @@ module WebMockHelper
28
28
 
29
29
  def response_for(response_file, options = {})
30
30
  response = {}
31
- response[:body] = File.new(File.join(File.dirname(__FILE__), '../mock_response', response_file))
31
+ format = options[:format] || :json
32
+ if format == :json
33
+ response[:headers] = {
34
+ 'Content-Type': 'application/json'
35
+ }
36
+ end
37
+ response[:body] = File.new(File.join(File.dirname(__FILE__), '../mock_response', "#{response_file}.#{format}"))
32
38
  if options[:status]
33
39
  response[:status] = options[:status]
34
40
  end
@@ -2,25 +2,16 @@ require 'spec_helper'
2
2
 
3
3
  describe Rack::OAuth2::AccessToken::Authenticator do
4
4
  let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
5
- let(:request) { HTTP::Message.new_request(:get, URI.parse(resource_endpoint)) }
5
+ let(:request) { Faraday::Request.new(:get, URI.parse(resource_endpoint)) }
6
6
  let(:authenticator) { Rack::OAuth2::AccessToken::Authenticator.new(token) }
7
7
 
8
8
  shared_examples_for :authenticator do
9
9
  it 'should let the token authenticate the request' do
10
10
  expect(token).to receive(:authenticate).with(request)
11
- authenticator.filter_request(request)
11
+ authenticator.authenticate(request)
12
12
  end
13
13
  end
14
14
 
15
- context 'when Legacy token is given' do
16
- let(:token) do
17
- Rack::OAuth2::AccessToken::Legacy.new(
18
- access_token: 'access_token'
19
- )
20
- end
21
- it_behaves_like :authenticator
22
- end
23
-
24
15
  context 'when Bearer token is given' do
25
16
  let(:token) do
26
17
  Rack::OAuth2::AccessToken::Bearer.new(
@@ -29,15 +20,4 @@ describe Rack::OAuth2::AccessToken::Authenticator do
29
20
  end
30
21
  it_behaves_like :authenticator
31
22
  end
32
-
33
- context 'when MAC token is given' do
34
- let(:token) do
35
- Rack::OAuth2::AccessToken::MAC.new(
36
- access_token: 'access_token',
37
- mac_key: 'secret',
38
- mac_algorithm: 'hmac-sha-256'
39
- )
40
- end
41
- it_behaves_like :authenticator
42
- end
43
23
  end
@@ -7,11 +7,11 @@ describe Rack::OAuth2::AccessToken::Bearer do
7
7
  )
8
8
  end
9
9
  let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
10
- let(:request) { HTTPClient.new.send(:create_request, :post, URI.parse(resource_endpoint), {}, {hello: "world"}, {}) }
10
+ let(:request) { Faraday::Request.new(:post, URI.parse(resource_endpoint), '', {hello: "world"}, {}) }
11
11
 
12
12
  describe '.authenticate' do
13
13
  it 'should set Authorization header' do
14
- expect(request.header).to receive(:[]=).with('Authorization', 'Bearer access_token')
14
+ expect(request.headers).to receive(:[]=).with('Authorization', 'Bearer access_token')
15
15
  token.authenticate(request)
16
16
  end
17
17
  end
@@ -49,23 +49,6 @@ describe Rack::OAuth2::AccessToken do
49
49
 
50
50
  let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
51
51
  [:get, :delete, :post, :put].each do |method|
52
- describe method do
53
- it 'should delegate to HTTPClient with Authenticator filter' do
54
- expect(token.httpclient).to receive(method).with(resource_endpoint)
55
- token.httpclient.request_filter.last.should be_a Rack::OAuth2::AccessToken::Authenticator
56
- token.send method, resource_endpoint
57
- end
58
- end
59
-
60
- context 'in debug mode' do
61
- it do
62
- Rack::OAuth2.debug do
63
- token.httpclient.request_filter[-2].should be_a Rack::OAuth2::AccessToken::Authenticator
64
- token.httpclient.request_filter.last.should be_a Rack::OAuth2::Debugger::RequestFilter
65
- end
66
- end
67
- end
68
-
69
52
  context 'when extension params given' do
70
53
  subject do
71
54
  Rack::OAuth2::AccessToken::Bearer.new(