rack-oauth2 1.19.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +3 -0
  3. data/.github/workflows/spec.yml +31 -0
  4. data/CHANGELOG.md +31 -0
  5. data/README.rdoc +1 -20
  6. data/VERSION +1 -1
  7. data/lib/rack/oauth2/access_token/authenticator.rb +1 -10
  8. data/lib/rack/oauth2/access_token/bearer.rb +1 -1
  9. data/lib/rack/oauth2/access_token/mtls.rb +2 -2
  10. data/lib/rack/oauth2/access_token.rb +4 -6
  11. data/lib/rack/oauth2/client.rb +86 -38
  12. data/lib/rack/oauth2/server/abstract/error.rb +1 -1
  13. data/lib/rack/oauth2/server/extension/pkce.rb +1 -1
  14. data/lib/rack/oauth2/server/rails/response_ext.rb +3 -3
  15. data/lib/rack/oauth2/server/resource/error.rb +4 -4
  16. data/lib/rack/oauth2/server/resource.rb +0 -1
  17. data/lib/rack/oauth2/server/token/error.rb +1 -1
  18. data/lib/rack/oauth2/server/token.rb +3 -3
  19. data/lib/rack/oauth2.rb +11 -15
  20. data/rack-oauth2.gemspec +6 -4
  21. data/spec/helpers/webmock_helper.rb +8 -2
  22. data/spec/rack/oauth2/access_token/authenticator_spec.rb +2 -22
  23. data/spec/rack/oauth2/access_token/bearer_spec.rb +2 -2
  24. data/spec/rack/oauth2/access_token_spec.rb +0 -17
  25. data/spec/rack/oauth2/client_spec.rb +135 -75
  26. data/spec/rack/oauth2/oauth2_spec.rb +0 -43
  27. data/spec/rack/oauth2/server/authorize/error_spec.rb +6 -6
  28. data/spec/rack/oauth2/server/resource/bearer/error_spec.rb +2 -2
  29. data/spec/rack/oauth2/server/resource/bearer_spec.rb +9 -9
  30. data/spec/rack/oauth2/server/resource/error_spec.rb +14 -14
  31. data/spec/rack/oauth2/server/token/authorization_code_spec.rb +2 -2
  32. data/spec/rack/oauth2/server/token/error_spec.rb +5 -5
  33. data/spec/rack/oauth2/server/token_spec.rb +2 -2
  34. metadata +43 -47
  35. data/.travis.yml +0 -8
  36. data/lib/rack/oauth2/access_token/legacy.rb +0 -19
  37. data/lib/rack/oauth2/access_token/mac/sha256_hex_verifier.rb +0 -17
  38. data/lib/rack/oauth2/access_token/mac/signature.rb +0 -34
  39. data/lib/rack/oauth2/access_token/mac/verifier.rb +0 -44
  40. data/lib/rack/oauth2/access_token/mac.rb +0 -103
  41. data/lib/rack/oauth2/debugger/request_filter.rb +0 -30
  42. data/lib/rack/oauth2/debugger.rb +0 -3
  43. data/lib/rack/oauth2/server/resource/mac/error.rb +0 -24
  44. data/lib/rack/oauth2/server/resource/mac.rb +0 -36
  45. data/spec/mock_response/tokens/legacy.json +0 -5
  46. data/spec/mock_response/tokens/legacy.txt +0 -1
  47. data/spec/mock_response/tokens/legacy_without_expires_in.txt +0 -1
  48. data/spec/mock_response/tokens/mac.json +0 -8
  49. data/spec/rack/oauth2/access_token/legacy_spec.rb +0 -23
  50. data/spec/rack/oauth2/access_token/mac/sha256_hex_verifier_spec.rb +0 -28
  51. data/spec/rack/oauth2/access_token/mac/signature_spec.rb +0 -59
  52. data/spec/rack/oauth2/access_token/mac/verifier_spec.rb +0 -25
  53. data/spec/rack/oauth2/access_token/mac_spec.rb +0 -141
  54. data/spec/rack/oauth2/debugger/request_filter_spec.rb +0 -33
  55. data/spec/rack/oauth2/server/resource/mac/error_spec.rb +0 -52
  56. data/spec/rack/oauth2/server/resource/mac_spec.rb +0 -119
  57. /data/spec/mock_response/{blank → blank.txt} +0 -0
@@ -1,59 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Rack::OAuth2::AccessToken::MAC::Signature do
4
- # From the example of Webtopay wallet API
5
- # ref) https://www.webtopay.com/wallet/
6
- context 'when ext is not given' do
7
- subject do
8
- Rack::OAuth2::AccessToken::MAC::Signature.new(
9
- secret: 'IrdTc8uQodU7PRpLzzLTW6wqZAO6tAMU',
10
- algorithm: 'hmac-sha-256',
11
- nonce: 'dj83hs9s',
12
- ts: 1336363200,
13
- method: 'GET',
14
- request_uri: '/wallet/rest/api/v1/payment/123',
15
- host: 'www.webtopay.com',
16
- port: 443
17
- )
18
- end
19
- its(:calculate) { should == 'OZE9fTk2qiRtL1jb01L8lRxC66PTiAGhMDEmboeVeLs=' }
20
- end
21
-
22
- # From the example of MAC spec section 1.1
23
- # ref) http://tools.ietf.org/pdf/draft-ietf-oauth-v2-http-mac-01.pdf
24
- context 'when ext is not given' do
25
- subject do
26
- Rack::OAuth2::AccessToken::MAC::Signature.new(
27
- secret: '489dks293j39',
28
- algorithm: 'hmac-sha-1',
29
- nonce: 'dj83hs9s',
30
- ts: 1336363200,
31
- method: 'GET',
32
- request_uri: '/resource/1?b=1&a=2',
33
- host: 'example.com',
34
- port: 80
35
- )
36
- end
37
- its(:calculate) { should == '6T3zZzy2Emppni6bzL7kdRxUWL4=' }
38
- end
39
-
40
- # From the example of MAC spec section 3.2
41
- # ref) http://tools.ietf.org/pdf/draft-ietf-oauth-v2-http-mac-01.pdf
42
- context 'otherwise' do
43
- subject do
44
- Rack::OAuth2::AccessToken::MAC::Signature.new(
45
- secret: '489dks293j39',
46
- algorithm: 'hmac-sha-1',
47
- nonce: '7d8f3e4a',
48
- ts: 264095,
49
- method: 'POST',
50
- request_uri: '/request?b5=%3D%253D&a3=a&c%40=&a2=r%20b&c2&a3=2+q',
51
- host: 'example.com',
52
- port: 80,
53
- ext: 'a,b,c'
54
- )
55
- end
56
- its(:calculate) { should == '+txL5oOFHGYjrfdNYH5VEzROaBY=' }
57
- end
58
-
59
- end
@@ -1,25 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Rack::OAuth2::AccessToken::MAC::Verifier do
4
- let(:verifier) { Rack::OAuth2::AccessToken::MAC::Verifier.new(algorithm: algorithm) }
5
- subject { verifier }
6
-
7
- context 'when "hmac-sha-1" is specified' do
8
- let(:algorithm) { 'hmac-sha-1' }
9
- its(:hash_generator) { should be_instance_of OpenSSL::Digest::SHA1 }
10
- end
11
-
12
- context 'when "hmac-sha-256" is specified' do
13
- let(:algorithm) { 'hmac-sha-256' }
14
- its(:hash_generator) { should be_instance_of OpenSSL::Digest::SHA256 }
15
- end
16
-
17
- context 'otherwise' do
18
- let(:algorithm) { 'invalid' }
19
- it do
20
- expect { verifier.send(:hash_generator) }.to raise_error(StandardError, 'Unsupported Algorithm')
21
- end
22
- end
23
-
24
-
25
- end
@@ -1,141 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Rack::OAuth2::AccessToken::MAC do
4
- let(:ts) { 1305820234 }
5
- let :token do
6
- Rack::OAuth2::AccessToken::MAC.new(
7
- access_token: 'access_token',
8
- mac_key: 'secret',
9
- mac_algorithm: 'hmac-sha-256',
10
- ts: ts
11
- )
12
- end
13
- let :token_with_ext_verifier do
14
- Rack::OAuth2::AccessToken::MAC.new(
15
- access_token: 'access_token',
16
- mac_key: 'secret',
17
- mac_algorithm: 'hmac-sha-256',
18
- ts: ts,
19
- ext_verifier: Rack::OAuth2::AccessToken::MAC::Sha256HexVerifier
20
- )
21
- end
22
- let(:nonce) { '1000:51e74de734c05613f37520872e68db5f' }
23
- let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
24
- subject { token }
25
-
26
- its(:mac_key) { should == 'secret' }
27
- its(:mac_algorithm) { should == 'hmac-sha-256' }
28
- its(:token_response) do
29
- should == {
30
- access_token: 'access_token',
31
- refresh_token: nil,
32
- token_type: :mac,
33
- expires_in: nil,
34
- scope: '',
35
- mac_key: 'secret',
36
- mac_algorithm: 'hmac-sha-256'
37
- }
38
- end
39
- its(:generate_nonce) { should be_a String }
40
-
41
- describe 'verify!' do
42
- let(:request) { Rack::OAuth2::Server::Resource::MAC::Request.new(env) }
43
-
44
- context 'when no ext_verifier is given' do
45
- let(:env) do
46
- Rack::MockRequest.env_for(
47
- '/protected_resources',
48
- 'HTTP_AUTHORIZATION' => %{MAC id="access_token", nonce="#{nonce}", ts="#{ts}" mac="#{signature}"}
49
- )
50
- end
51
-
52
- context 'when signature is valid' do
53
- let(:signature) { 'BgooS/voPOZWLwoVfx4+zbC3xAVKW3jtjhKYOfIGZOA=' }
54
- it do
55
-
56
- token.verify!(request.setup!).should == :verified
57
- end
58
- end
59
-
60
- context 'otherwise' do
61
- let(:signature) { 'invalid' }
62
- it do
63
- expect { token.verify!(request.setup!) }.to raise_error(
64
- Rack::OAuth2::Server::Resource::MAC::Unauthorized,
65
- 'invalid_token :: Signature Invalid'
66
- )
67
- end
68
- end
69
- end
70
-
71
- context 'when ext_verifier is given' do
72
- let(:env) do
73
- Rack::MockRequest.env_for(
74
- '/protected_resources',
75
- method: :POST,
76
- params: {
77
- key1: 'value1'
78
- },
79
- 'HTTP_AUTHORIZATION' => %{MAC id="access_token", nonce="#{nonce}", ts="#{ts}", mac="#{signature}", ext="#{ext}"}
80
- )
81
- end
82
- let(:signature) { 'invalid' }
83
-
84
- context 'when ext is invalid' do
85
- let(:ext) { 'invalid' }
86
- it do
87
- expect { token_with_ext_verifier.verify!(request.setup!) }.to raise_error(
88
- Rack::OAuth2::Server::Resource::MAC::Unauthorized,
89
- 'invalid_token :: Sha256HexVerifier Invalid'
90
- )
91
- end
92
- end
93
-
94
- context 'when ext is valid' do
95
- let(:ext) { '4cfcd46c59f54b5ea6a5f9b05c28b52fef2864747194b5fdfc3d59c0057bf35a' }
96
-
97
- context 'when signature is valid' do
98
- let(:signature) { 'dZYR54n+Lym5qCRRmDqmRZ71rG+bkjSWmqrOv8OjYHk=' }
99
- it do
100
- Time.fix(Time.at(1302361200)) do
101
- token_with_ext_verifier.verify!(request.setup!).should == :verified
102
- end
103
- end
104
- end
105
-
106
- context 'otherwise' do
107
- it do
108
- expect { token.verify!(request.setup!) }.to raise_error(
109
- Rack::OAuth2::Server::Resource::MAC::Unauthorized,
110
- 'invalid_token :: Signature Invalid'
111
- )
112
- end
113
- end
114
- end
115
- end
116
- end
117
-
118
- describe '.authenticate' do
119
- let(:request) { HTTPClient.new.send(:create_request, :post, URI.parse(resource_endpoint), {}, {hello: "world"}, {}) }
120
- context 'when no ext_verifier is given' do
121
- let(:signature) { 'pOBaL6HRawe4tUPmcU4vJEj1f2GJqrbQOlCcdAYgI/s=' }
122
-
123
- it 'should set Authorization header' do
124
- expect(token).to receive(:generate_nonce).and_return(nonce)
125
- expect(request.header).to receive(:[]=).with('Authorization', "MAC id=\"access_token\", nonce=\"#{nonce}\", ts=\"#{ts.to_i}\", mac=\"#{signature}\"")
126
- token.authenticate(request)
127
- end
128
- end
129
-
130
- context 'when ext_verifier is given' do
131
- let(:signature) { 'vgU0fj6rSpwUCAoCOrXlu8pZBR8a5Q5xIVlB4MCvJeM=' }
132
- let(:ext) { '3d011e09502a84552a0f8ae112d024cc2c115597e3a577d5f49007902c221dc5' }
133
- it 'should set Authorization header with ext_verifier' do
134
- expect(token_with_ext_verifier).to receive(:generate_nonce).and_return(nonce)
135
- expect(request.header).to receive(:[]=).with('Authorization', "MAC id=\"access_token\", nonce=\"#{nonce}\", ts=\"#{ts.to_i}\", mac=\"#{signature}\", ext=\"#{ext}\"")
136
- token_with_ext_verifier.authenticate(request)
137
- end
138
- end
139
-
140
- end
141
- end
@@ -1,33 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Rack::OAuth2::Debugger::RequestFilter do
4
- let(:resource_endpoint) { 'https://example.com/resources' }
5
- let(:request) { HTTP::Message.new_request(:get, URI.parse(resource_endpoint)) }
6
- let(:response) { HTTP::Message.new_response({hello: 'world'}.to_json) }
7
- let(:request_filter) { Rack::OAuth2::Debugger::RequestFilter.new }
8
-
9
- describe '#filter_request' do
10
- it 'should log request' do
11
- [
12
- "======= [Rack::OAuth2] HTTP REQUEST STARTED =======",
13
- request.dump
14
- ].each do |output|
15
- expect(Rack::OAuth2.logger).to receive(:info).with output
16
- end
17
- request_filter.filter_request(request)
18
- end
19
- end
20
-
21
- describe '#filter_response' do
22
- it 'should log response' do
23
- [
24
- "--------------------------------------------------",
25
- response.dump,
26
- "======= [Rack::OAuth2] HTTP REQUEST FINISHED ======="
27
- ].each do |output|
28
- expect(Rack::OAuth2.logger).to receive(:info).with output
29
- end
30
- request_filter.filter_response(request, response)
31
- end
32
- end
33
- end
@@ -1,52 +0,0 @@
1
- require 'spec_helper.rb'
2
-
3
- describe Rack::OAuth2::Server::Resource::MAC::Unauthorized do
4
- let(:error) { Rack::OAuth2::Server::Resource::MAC::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 == :MAC }
11
- end
12
-
13
- describe '#finish' do
14
- it 'should use MAC scheme' do
15
- status, header, response = error.finish
16
- header['WWW-Authenticate'].should =~ /^MAC /
17
- end
18
- end
19
- end
20
-
21
- describe Rack::OAuth2::Server::Resource::MAC::ErrorMethods do
22
- let(:unauthorized) { Rack::OAuth2::Server::Resource::MAC::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::MAC::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
@@ -1,119 +0,0 @@
1
- require 'spec_helper.rb'
2
-
3
- describe Rack::OAuth2::Server::Resource::MAC do
4
- let(:app) do
5
- Rack::OAuth2::Server::Resource::MAC.new(simple_app) do |request|
6
- case request.access_token
7
- when 'valid_token'
8
- token = mac_token
9
- token.verify!(request)
10
- token
11
- when 'insufficient_scope_token'
12
- request.insufficient_scope!
13
- else
14
- request.invalid_token!
15
- end
16
- end
17
- end
18
- let(:mac_token) do
19
- Rack::OAuth2::AccessToken::MAC.new(
20
- access_token: 'valid_token',
21
- mac_key: 'secret',
22
- mac_algorithm: 'hmac-sha-256',
23
- ts: 1305820230 # fix verification time
24
- )
25
- end
26
- let(:access_token) { env[Rack::OAuth2::Server::Resource::ACCESS_TOKEN] }
27
- let(:request) { app.call(env) }
28
- subject { app.call(env) }
29
-
30
- shared_examples_for :non_mac_request do
31
- it 'should skip OAuth 2.0 authentication' do
32
- status, header, response = request
33
- status.should == 200
34
- access_token.should be_nil
35
- end
36
- end
37
- shared_examples_for :authenticated_mac_request do
38
- it 'should be authenticated' do
39
- status, header, response = request
40
- status.should == 200
41
- access_token.should == mac_token
42
- end
43
- end
44
- shared_examples_for :unauthorized_mac_request do
45
- it 'should be unauthorized' do
46
- status, header, response = request
47
- status.should == 401
48
- header['WWW-Authenticate'].should include 'MAC'
49
- access_token.should be_nil
50
- end
51
- end
52
- shared_examples_for :bad_mac_request do
53
- it 'should be unauthorized' do
54
- status, header, response = request
55
- status.should == 400
56
- access_token.should be_nil
57
- end
58
- end
59
-
60
- context 'when no access token is given' do
61
- let(:env) { Rack::MockRequest.env_for('/protected_resource') }
62
- it 'should skip OAuth 2.0 authentication' do
63
- status, header, response = request
64
- status.should == 200
65
- access_token.should be_nil
66
- end
67
- end
68
-
69
- context 'when valid_token is given' do
70
- context 'when other required params are missing' do
71
- let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'MAC id="valid_token"') }
72
- it_behaves_like :unauthorized_mac_request
73
- end
74
-
75
- context 'when other required params are invalid' do
76
- let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'MAC id="valid_token", nonce="51e74de734c05613f37520872e68db5f", ts="1305820234", mac="invalid""') }
77
- it_behaves_like :unauthorized_mac_request
78
- end
79
-
80
- context 'when all required params are valid' do
81
- let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'MAC id="valid_token", nonce="51e74de734c05613f37520872e68db5f", ts="1305820234", mac="26JP6MMZyAHLHeMU8+m+NbVJgZbikp5SlT86/a62pwg="') }
82
- it_behaves_like :authenticated_mac_request
83
- end
84
-
85
- context 'when all required params are valid and ts is expired' do
86
- let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'MAC id="valid_token", nonce="51e74de734c05613f37520872e68db5f", ts="1305819234", mac="nuo4765MZrVL/qMsAtuTczhqZAE5y02ChaLCyOiVU68="') }
87
- it_behaves_like :unauthorized_mac_request
88
- end
89
- end
90
-
91
- context 'when invalid_token is given' do
92
- let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'MAC id="invalid_token"') }
93
- it_behaves_like :unauthorized_mac_request
94
-
95
- describe 'realm' do
96
- let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'MAC id="invalid_token"') }
97
-
98
- context 'when specified' do
99
- let(:realm) { 'server.example.com' }
100
- let(:app) do
101
- Rack::OAuth2::Server::Resource::MAC.new(simple_app, realm) do |request|
102
- request.unauthorized!
103
- end
104
- end
105
- it 'should use specified realm' do
106
- status, header, response = request
107
- header['WWW-Authenticate'].should include "MAC realm=\"#{realm}\""
108
- end
109
- end
110
-
111
- context 'otherwize' do
112
- it 'should use default realm' do
113
- status, header, response = request
114
- header['WWW-Authenticate'].should include "MAC realm=\"#{Rack::OAuth2::Server::Resource::DEFAULT_REALM}\""
115
- end
116
- end
117
- end
118
- end
119
- end
File without changes