rack-oauth2 1.13.0.beta → 1.17.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c7df75ac6f0aeaca6d60b3a58992d1224d0ec1575913ab7e0b8750b628410247
4
- data.tar.gz: b5577a6b9cde7789a0680e1953aca60917efcade9ffa81c62614ad45adf2cc23
3
+ metadata.gz: 5ea33651fcefd142210b8b6c275eb6a3c6096274796ef3070a5fa87da18433a6
4
+ data.tar.gz: 284e253fbefbe51cc1d645ec348584160c6f4363251f908ea536d1796b3444e5
5
5
  SHA512:
6
- metadata.gz: ff5bf461923229f5e444735bccf0d6010b1a938818df96f80e0db1d9decf1b1f0b24dba9d47320974dce5d53324798460fb24f56d30c678cf553401128049418
7
- data.tar.gz: 55e0119a9311350f42a2a2d6daf3101cd9b451a9cd88948eaf16b9fc8b3648dc2912cc6066b8043fa380c5a55ef225a9bfb68ebbe199443717eab9ad5ee22e86
6
+ metadata.gz: ae2c8ced737f24a116a0b484d745477e8e4b03732e5a7147428e4d63fee61518ca43a705020817b09311ac030267e1b55ab072f421b26a90292482945c9b3bd3
7
+ data.tar.gz: 2e70af95a0040f956e3de8d918d50c3322107f68cb7a5af25a9987cac914c40d6453202e97e42395bf1707e78b65987f0b059b9c77bf3421070ee6f51a2dddd3
data/.travis.yml CHANGED
@@ -4,4 +4,5 @@ before_install:
4
4
  rvm:
5
5
  - 2.5.8
6
6
  - 2.6.6
7
- - 2.7.1
7
+ - 2.7.2
8
+ - 3.0.0
data/README.rdoc CHANGED
@@ -28,17 +28,11 @@ http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01
28
28
 
29
29
  === Bearer
30
30
 
31
- Running on Heroku
32
- https://rack-oauth2-sample.heroku.com
33
-
34
31
  Source on GitHub
35
32
  https://github.com/nov/rack-oauth2-sample
36
33
 
37
34
  === MAC
38
35
 
39
- Running on Heroku
40
- https://rack-oauth2-sample-mac.heroku.com
41
-
42
36
  Source on GitHub
43
37
  https://github.com/nov/rack-oauth2-sample-mac
44
38
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.13.0.beta
1
+ 1.17.0
@@ -16,12 +16,12 @@ module Rack
16
16
  end
17
17
 
18
18
  def authorization_uri(params = {})
19
+ params[:redirect_uri] ||= self.redirect_uri
19
20
  params[:response_type] ||= :code
20
21
  params[:response_type] = Array(params[:response_type]).join(' ')
21
22
  params[:scope] = Array(params[:scope]).join(' ')
22
23
  Util.redirect_uri absolute_uri_for(authorization_endpoint), :query, params.merge(
23
- client_id: self.identifier,
24
- redirect_uri: self.redirect_uri
24
+ client_id: self.identifier
25
25
  )
26
26
  end
27
27
 
@@ -73,16 +73,24 @@ module Rack
73
73
  http_client = Rack::OAuth2.http_client
74
74
 
75
75
  # NOTE:
76
- # Using Array#estract_options! for backward compatibility.
76
+ # Using Array#extract_options! for backward compatibility.
77
77
  # Until v1.0.5, the first argument was 'client_auth_method' in scalar.
78
78
  options = args.extract_options!
79
- client_auth_method = args.first || options.delete(:client_auth_method) || :basic
79
+ client_auth_method = args.first || options.delete(:client_auth_method).try(:to_sym) || :basic
80
80
 
81
81
  params[:scope] = Array(options.delete(:scope)).join(' ') if options[:scope].present?
82
82
  params.merge! options
83
83
 
84
84
  case client_auth_method
85
85
  when :basic
86
+ cred = Base64.strict_encode64 [
87
+ Util.www_form_url_encode(identifier),
88
+ Util.www_form_url_encode(secret)
89
+ ].join(':')
90
+ headers.merge!(
91
+ 'Authorization' => "Basic #{cred}"
92
+ )
93
+ when :basic_without_www_form_urlencode
86
94
  cred = ["#{identifier}:#{secret}"].pack('m').tr("\n", '')
87
95
  headers.merge!(
88
96
  'Authorization' => "Basic #{cred}"
@@ -49,7 +49,9 @@ module Rack
49
49
  def initialize(env)
50
50
  auth = Rack::Auth::Basic::Request.new(env)
51
51
  if auth.provided? && auth.basic?
52
- @client_id, @client_secret = auth.credentials
52
+ @client_id, @client_secret = auth.credentials.map do |cred|
53
+ Util.www_form_url_decode cred
54
+ end
53
55
  super
54
56
  else
55
57
  super
@@ -3,14 +3,14 @@ module Rack
3
3
  module URN
4
4
  module TokenType
5
5
  JWT = 'urn:ietf:params:oauth:token-type:jwt' # RFC7519
6
- ACCESS_TOKEN = 'urn:ietf:params:oauth:token-type:access-token' # draft-ietf-oauth-token-exchange
7
- REFRESH_TOKEN = 'urn:ietf:params:oauth:token-type:refresh-token' # draft-ietf-oauth-token-exchange
6
+ ACCESS_TOKEN = 'urn:ietf:params:oauth:token-type:access_token' # RFC8693
7
+ REFRESH_TOKEN = 'urn:ietf:params:oauth:token-type:refresh_token' # RFC8693
8
8
  end
9
9
 
10
10
  module GrantType
11
11
  JWT_BEARER = 'urn:ietf:params:oauth:grant-type:jwt-bearer' # RFC7523
12
12
  SAML2_BEARER = 'urn:ietf:params:oauth:grant-type:saml2-bearer' # RFC7522
13
- TOKEN_EXCHANGE = 'urn:ietf:params:oauth:grant-type:token-exchange' # draft-ietf-oauth-token-exchange
13
+ TOKEN_EXCHANGE = 'urn:ietf:params:oauth:grant-type:token-exchange' # RFC8693
14
14
  end
15
15
 
16
16
  module ClientAssertionType
@@ -4,8 +4,12 @@ module Rack
4
4
  module OAuth2
5
5
  module Util
6
6
  class << self
7
- def rfc3986_encode(text)
8
- URI.encode(text, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
7
+ def www_form_url_encode(text)
8
+ URI.encode_www_form_component(text)
9
+ end
10
+
11
+ def www_form_url_decode(text)
12
+ URI.decode_www_form_component(text)
9
13
  end
10
14
 
11
15
  def base64_encode(text)
@@ -1,10 +1,12 @@
1
1
  require 'spec_helper.rb'
2
2
 
3
3
  describe Rack::OAuth2::Client do
4
+ let(:client_id) { 'client_id' }
5
+ let(:client_secret) { 'client_secret' }
4
6
  let :client do
5
7
  Rack::OAuth2::Client.new(
6
- identifier: 'client_id',
7
- secret: 'client_secret',
8
+ identifier: client_id,
9
+ secret: client_secret,
8
10
  host: 'server.example.com',
9
11
  redirect_uri: 'https://client.example.com/callback'
10
12
  )
@@ -97,6 +99,42 @@ describe Rack::OAuth2::Client do
97
99
  client.access_token!
98
100
  end
99
101
 
102
+ context 'when Basic auth method is used' do
103
+ context 'when client_id is a url' do
104
+ let(:client_id) { 'https://client.example.com'}
105
+
106
+ it 'should be encoded in "application/x-www-form-urlencoded"' do
107
+ mock_response(
108
+ :post,
109
+ 'https://server.example.com/oauth2/token',
110
+ 'tokens/bearer.json',
111
+ request_header: {
112
+ 'Authorization' => 'Basic aHR0cHMlM0ElMkYlMkZjbGllbnQuZXhhbXBsZS5jb206Y2xpZW50X3NlY3JldA=='
113
+ }
114
+ )
115
+ client.access_token!
116
+ end
117
+ end
118
+ end
119
+
120
+ context 'when basic_without_www_form_urlencode method is used' do
121
+ context 'when client_id is a url' do
122
+ let(:client_id) { 'https://client.example.com'}
123
+
124
+ it 'should be encoded in "application/x-www-form-urlencoded"' do
125
+ mock_response(
126
+ :post,
127
+ 'https://server.example.com/oauth2/token',
128
+ 'tokens/bearer.json',
129
+ request_header: {
130
+ 'Authorization' => 'Basic aHR0cHM6Ly9jbGllbnQuZXhhbXBsZS5jb206Y2xpZW50X3NlY3JldA=='
131
+ }
132
+ )
133
+ client.access_token! :basic_without_www_form_urlencode
134
+ end
135
+ end
136
+ end
137
+
100
138
  context 'when jwt_bearer auth method specified' do
101
139
  context 'when client_secret is given' do
102
140
  it 'should be JWT bearer client assertion w/ auto-generated HS256-signed JWT assertion' do
@@ -4,14 +4,19 @@ describe Rack::OAuth2::Server::Token::ClientCredentials do
4
4
  let(:request) { Rack::MockRequest.new app }
5
5
  let(:app) do
6
6
  Rack::OAuth2::Server::Token.new do |request, response|
7
+ unless request.client_id == client_id && request.client_secret == client_secret
8
+ request.invalid_client!
9
+ end
7
10
  response.access_token = Rack::OAuth2::AccessToken::Bearer.new(access_token: 'access_token')
8
11
  end
9
12
  end
13
+ let(:client_id) { 'client_id '}
14
+ let(:client_secret) { 'client_secret' }
10
15
  let(:params) do
11
16
  {
12
17
  grant_type: 'client_credentials',
13
- client_id: 'client_id',
14
- client_secret: 'client_secret'
18
+ client_id: client_id,
19
+ client_secret: client_secret
15
20
  }
16
21
  end
17
22
  subject { request.post('/', params: params) }
@@ -20,4 +25,29 @@ describe Rack::OAuth2::Server::Token::ClientCredentials do
20
25
  its(:content_type) { should == 'application/json' }
21
26
  its(:body) { should include '"access_token":"access_token"' }
22
27
  its(:body) { should include '"token_type":"bearer"' }
28
+
29
+ context 'basic auth' do
30
+ let(:params) do
31
+ { grant_type: 'client_credentials' }
32
+ end
33
+ let(:encoded_creds) do
34
+ Base64.strict_encode64([
35
+ Rack::OAuth2::Util.www_form_url_encode(client_id),
36
+ Rack::OAuth2::Util.www_form_url_encode(client_secret)
37
+ ].join(':'))
38
+ end
39
+ subject do
40
+ request.post('/',
41
+ {params: params, 'HTTP_AUTHORIZATION' => "Basic #{encoded_creds}"})
42
+ end
43
+
44
+ its(:status) { should == 200 }
45
+
46
+ context 'compliance with RFC6749 sec 2.3.1' do
47
+ let(:client_id) { 'client: yes/please!' }
48
+ let(:client_secret) { 'terrible:secret:of:space' }
49
+
50
+ its(:status) { should == 200 }
51
+ end
52
+ end
23
53
  end
@@ -9,9 +9,14 @@ describe Rack::OAuth2::Util do
9
9
  'http://client.example.com/callback'
10
10
  end
11
11
 
12
- describe '.rfc3986_encode' do
13
- subject { util.rfc3986_encode '=+ .-/' }
14
- it { should == '%3D%2B%20.-%2F' }
12
+ describe '.www_form_url_encode' do
13
+ subject { util.www_form_url_encode '=+ .-/' }
14
+ it { should == '%3D%2B+.-%2F' }
15
+ end
16
+
17
+ describe '.www_form_urldecode' do
18
+ subject { util.www_form_url_decode '%3D%2B+.-%2F' }
19
+ it { should == '=+ .-/' }
15
20
  end
16
21
 
17
22
  describe '.base64_encode' 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: 1.13.0.beta
4
+ version: 1.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - nov matake
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-21 00:00:00.000000000 Z
11
+ date: 2021-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -297,9 +297,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
297
297
  version: '0'
298
298
  required_rubygems_version: !ruby/object:Gem::Requirement
299
299
  requirements:
300
- - - ">"
300
+ - - ">="
301
301
  - !ruby/object:Gem::Version
302
- version: 1.3.1
302
+ version: '0'
303
303
  requirements: []
304
304
  rubygems_version: 3.0.3
305
305
  signing_key: