rack-oauth2 1.12.0 → 2.2.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 +4 -4
- data/.github/FUNDING.yml +3 -0
- data/.github/workflows/spec.yml +32 -0
- data/CHANGELOG.md +25 -0
- data/README.rdoc +1 -26
- 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 +97 -41
- 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 +5 -5
- 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 +16 -5
- data/lib/rack/oauth2/urn.rb +3 -3
- data/lib/rack/oauth2/util.rb +6 -2
- data/lib/rack/oauth2.rb +11 -10
- data/rack-oauth2.gemspec +7 -5
- 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 +173 -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 +21 -21
- data/spec/rack/oauth2/server/token/authorization_code_spec.rb +2 -2
- data/spec/rack/oauth2/server/token/client_credentials_spec.rb +32 -2
- data/spec/rack/oauth2/server/token/error_spec.rb +8 -8
- data/spec/rack/oauth2/server/token_spec.rb +72 -3
- data/spec/rack/oauth2/util_spec.rb +8 -3
- metadata +47 -51
- data/.travis.yml +0 -7
- 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
@@ -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
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Rack::OAuth2::AccessToken::Legacy do
|
4
|
-
let :token do
|
5
|
-
Rack::OAuth2::AccessToken::Legacy.new(
|
6
|
-
access_token: 'access_token'
|
7
|
-
)
|
8
|
-
end
|
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"}, {}) }
|
11
|
-
|
12
|
-
describe '#to_s' do
|
13
|
-
subject { token }
|
14
|
-
its(:to_s) { should == token.access_token }
|
15
|
-
end
|
16
|
-
|
17
|
-
describe '.authenticate' do
|
18
|
-
it 'should set Authorization header' do
|
19
|
-
expect(request.header).to receive(:[]=).with('Authorization', 'OAuth access_token')
|
20
|
-
token.authenticate(request)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Rack::OAuth2::AccessToken::MAC::Sha256HexVerifier do
|
4
|
-
|
5
|
-
# From the example of webtopay wallet API spec
|
6
|
-
# ref) https://www.webtopay.com/wallet/#authentication
|
7
|
-
context 'when example from webtopay wallet API' do
|
8
|
-
subject do
|
9
|
-
Rack::OAuth2::AccessToken::MAC::Sha256HexVerifier.new(
|
10
|
-
algorithm: 'hmac-sha-256',
|
11
|
-
raw_body: 'grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=http%3A%2F%2Flocalhost%2Fabc'
|
12
|
-
)
|
13
|
-
end
|
14
|
-
its(:calculate) { should == '21fb73c40b589622d0c78e9cd8900f89d9472aa724d0e5c3eca9ac1cd9d2a6d5' }
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
|
-
context 'when raw_body is empty' do
|
19
|
-
subject do
|
20
|
-
Rack::OAuth2::AccessToken::MAC::Sha256HexVerifier.new(
|
21
|
-
algorithm: 'hmac-sha-256',
|
22
|
-
raw_body: ''
|
23
|
-
)
|
24
|
-
end
|
25
|
-
its(:calculate) { should be_nil }
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
@@ -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
|