rack-oauth2 1.21.3 → 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.
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(