rack-oauth2-1.9.3/ 0000755 0000041 0000041 00000000000 13410611536 013674 5 ustar www-data www-data rack-oauth2-1.9.3/.travis.yml 0000644 0000041 0000041 00000000114 13410611536 016001 0 ustar www-data www-data before_install:
- gem install bundler
rvm:
- 2.3.6
- 2.4.3
- 2.5.0
rack-oauth2-1.9.3/rack-oauth2.gemspec 0000644 0000041 0000041 00000002172 13410611536 017363 0 ustar www-data www-data Gem::Specification.new do |s|
s.name = 'rack-oauth2'
s.version = File.read('VERSION')
s.authors = ['nov matake']
s.description = %q{OAuth 2.0 Server & Client Library. Both Bearer and MAC token type are supported.}
s.summary = %q{OAuth 2.0 Server & Client Library - Both Bearer and MAC token type are supported}
s.email = 'nov@matake.jp'
s.extra_rdoc_files = ['LICENSE', 'README.rdoc']
s.rdoc_options = ['--charset=UTF-8']
s.homepage = 'http://github.com/nov/rack-oauth2'
s.license = 'MIT'
s.require_paths = ['lib']
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.add_runtime_dependency 'rack'
s.add_runtime_dependency 'httpclient'
s.add_runtime_dependency 'activesupport'
s.add_runtime_dependency 'attr_required'
s.add_runtime_dependency 'json-jwt', '>= 1.9.0'
s.add_development_dependency 'rake'
s.add_development_dependency 'simplecov'
s.add_development_dependency 'rspec'
s.add_development_dependency 'rspec-its'
s.add_development_dependency 'webmock'
end
rack-oauth2-1.9.3/.rspec 0000644 0000041 0000041 00000000037 13410611536 015011 0 ustar www-data www-data --color
--format=documentation
rack-oauth2-1.9.3/spec/ 0000755 0000041 0000041 00000000000 13410611536 014626 5 ustar www-data www-data rack-oauth2-1.9.3/spec/helpers/ 0000755 0000041 0000041 00000000000 13410611536 016270 5 ustar www-data www-data rack-oauth2-1.9.3/spec/helpers/webmock_helper.rb 0000644 0000041 0000041 00000001635 13410611536 021610 0 ustar www-data www-data require 'webmock/rspec'
module WebMockHelper
def mock_response(method, endpoint, response_file, options = {})
stub_request(method, endpoint).with(
request_for(method, options)
).to_return(
response_for(response_file, options)
)
end
private
def request_for(method, options = {})
request = {}
params = options.try(:[], :params) || {}
case method
when :post, :put, :delete
request[:body] = params
else
request[:query] = params
end
if options[:request_header]
request[:headers] = options[:request_header]
end
request
end
def response_for(response_file, options = {})
response = {}
response[:body] = File.new(File.join(File.dirname(__FILE__), '../mock_response', response_file))
if options[:status]
response[:status] = options[:status]
end
response
end
end
include WebMockHelper
WebMock.disable_net_connect! rack-oauth2-1.9.3/spec/helpers/time.rb 0000644 0000041 0000041 00000000506 13410611536 017554 0 ustar www-data www-data class Time
class << self
module NowWithFixedTime
def now
if @fixed_time
@fixed_time.dup
else
super
end
end
end
prepend NowWithFixedTime
def fix(time = Time.now)
@fixed_time = time
yield
ensure
@fixed_time = nil
end
end
end
rack-oauth2-1.9.3/spec/rack/ 0000755 0000041 0000041 00000000000 13410611536 015546 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/ 0000755 0000041 0000041 00000000000 13410611536 016750 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/client/ 0000755 0000041 0000041 00000000000 13410611536 020226 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/client/grant/ 0000755 0000041 0000041 00000000000 13410611536 021341 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/client/grant/client_credentials_spec.rb 0000644 0000041 0000041 00000000242 13410611536 026531 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Client::Grant::ClientCredentials do
its(:as_json) do
should == {grant_type: :client_credentials}
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/client/grant/password_spec.rb 0000644 0000041 0000041 00000001431 13410611536 024541 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Client::Grant::Password do
let(:grant) { Rack::OAuth2::Client::Grant::Password }
context 'when username is given' do
let :attributes do
{username: 'username'}
end
context 'when password is given' do
let :attributes do
{username: 'username', password: 'password'}
end
subject { grant.new attributes }
its(:as_json) do
should == {grant_type: :password, username: 'username', password: 'password'}
end
end
context 'otherwise' do
it do
expect { grant.new attributes }.to raise_error AttrRequired::AttrMissing
end
end
end
context 'otherwise' do
it do
expect { grant.new }.to raise_error AttrRequired::AttrMissing
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/client/grant/jwt_bearer_spec.rb 0000644 0000041 0000041 00000001064 13410611536 025025 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Client::Grant::JWTBearer do
let(:grant) { Rack::OAuth2::Client::Grant::JWTBearer }
context 'when JWT assertion is given' do
let :attributes do
{assertion: 'header.payload.signature'}
end
subject { grant.new attributes }
its(:as_json) do
should == {grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', assertion: 'header.payload.signature'}
end
end
context 'otherwise' do
it do
expect { grant.new }.to raise_error AttrRequired::AttrMissing
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/client/grant/authorization_code_spec.rb 0000644 0000041 0000041 00000001775 13410611536 026604 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Client::Grant::AuthorizationCode do
let(:redirect_uri) { 'https://client.example.com/callback' }
let(:grant) { Rack::OAuth2::Client::Grant::AuthorizationCode }
context 'when code is given' do
let :attributes do
{code: 'code'}
end
context 'when redirect_uri is given' do
let :attributes do
{code: 'code', redirect_uri: redirect_uri}
end
subject { grant.new attributes }
its(:redirect_uri) { should == redirect_uri }
its(:as_json) do
should == {grant_type: :authorization_code, code: 'code', redirect_uri: redirect_uri}
end
end
context 'otherwise' do
subject { grant.new attributes }
its(:redirect_uri) { should be_nil }
its(:as_json) do
should == {grant_type: :authorization_code, code: 'code', redirect_uri: nil}
end
end
end
context 'otherwise' do
it do
expect { grant.new }.to raise_error AttrRequired::AttrMissing
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/client/grant/saml2_bearer_spec.rb 0000644 0000041 0000041 00000001046 13410611536 025237 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Client::Grant::SAML2Bearer do
let(:grant) { Rack::OAuth2::Client::Grant::SAML2Bearer }
context 'when JWT assertion is given' do
let :attributes do
{assertion: '...'}
end
subject { grant.new attributes }
its(:as_json) do
should == {grant_type: 'urn:ietf:params:oauth:grant-type:saml2-bearer', assertion: '...'}
end
end
context 'otherwise' do
it do
expect { grant.new }.to raise_error AttrRequired::AttrMissing
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/client/grant/refresh_token_spec.rb 0000644 0000041 0000041 00000001015 13410611536 025533 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Client::Grant::RefreshToken do
let(:grant) { Rack::OAuth2::Client::Grant::RefreshToken }
context 'when refresh_token is given' do
let :attributes do
{refresh_token: 'refresh_token'}
end
subject { grant.new attributes }
its(:as_json) do
should == {grant_type: :refresh_token, refresh_token: 'refresh_token'}
end
end
context 'otherwise' do
it do
expect { grant.new }.to raise_error AttrRequired::AttrMissing
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/client/error_spec.rb 0000644 0000041 0000041 00000000743 13410611536 022722 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Client::Error do
let :error do
{
error: :invalid_request,
error_description: 'Include invalid parameters',
error_uri: 'http://server.example.com/error/invalid_request'
}
end
subject do
Rack::OAuth2::Client::Error.new 400, error
end
its(:status) { should == 400 }
its(:message) { should == [error[:error], error[:error_description]].join(' :: ') }
its(:response) { should == error }
end
rack-oauth2-1.9.3/spec/rack/oauth2/debugger/ 0000755 0000041 0000041 00000000000 13410611536 020534 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/debugger/request_filter_spec.rb 0000644 0000041 0000041 00000002061 13410611536 025127 0 ustar www-data www-data require 'spec_helper'
describe Rack::OAuth2::Debugger::RequestFilter do
let(:resource_endpoint) { 'https://example.com/resources' }
let(:request) { HTTP::Message.new_request(:get, URI.parse(resource_endpoint)) }
let(:response) { HTTP::Message.new_response({hello: 'world'}.to_json) }
let(:request_filter) { Rack::OAuth2::Debugger::RequestFilter.new }
describe '#filter_request' do
it 'should log request' do
[
"======= [Rack::OAuth2] HTTP REQUEST STARTED =======",
request.dump
].each do |output|
expect(Rack::OAuth2.logger).to receive(:info).with output
end
request_filter.filter_request(request)
end
end
describe '#filter_response' do
it 'should log response' do
[
"--------------------------------------------------",
response.dump,
"======= [Rack::OAuth2] HTTP REQUEST FINISHED ======="
].each do |output|
expect(Rack::OAuth2.logger).to receive(:info).with output
end
request_filter.filter_response(request, response)
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/util_spec.rb 0000644 0000041 0000041 00000004651 13410611536 021272 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Util do
let :util do
Rack::OAuth2::Util
end
let :uri do
'http://client.example.com/callback'
end
describe '.rfc3986_encode' do
subject { util.rfc3986_encode '=+ .-/' }
it { should == '%3D%2B%20.-%2F' }
end
describe '.base64_encode' do
subject { util.base64_encode '=+ .-/' }
it { should == 'PSsgLi0v' }
end
describe '.compact_hash' do
subject { util.compact_hash k1: 'v1', k2: '', k3: nil }
it { should == {k1: 'v1'} }
end
describe '.parse_uri' do
context 'when String is given' do
it { util.parse_uri(uri).should be_a URI::Generic }
end
context 'when URI is given' do
it 'should be itself' do
_uri_ = URI.parse uri
util.parse_uri(_uri_).should be _uri_
end
end
context 'when invalid URI is given' do
it do
expect do
util.parse_uri '::'
end.to raise_error URI::InvalidURIError
end
end
context 'otherwise' do
it do
expect { util.parse_uri nil }.to raise_error StandardError
expect { util.parse_uri 123 }.to raise_error StandardError
end
end
end
describe '.redirect_uri' do
let(:base_uri) { 'http://client.example.com' }
let(:params) do
{k1: :v1, k2: ''}
end
subject { util.redirect_uri base_uri, location, params }
context 'when location = :fragment' do
let(:location) { :fragment }
it { should == "#{base_uri}##{util.compact_hash(params).to_query}" }
end
context 'when location = :query' do
let(:location) { :query }
it { should == "#{base_uri}?#{util.compact_hash(params).to_query}" }
end
end
describe '.uri_match?' do
context 'when invalid URI is given' do
it do
util.uri_match?('::', '::').should == false
util.uri_match?(123, 'http://client.example.com/other').should == false
util.uri_match?('http://client.example.com/other', nil).should == false
end
end
context 'when exactly same' do
it { util.uri_match?(uri, uri).should == true }
end
context 'when path prefix matches' do
it { util.uri_match?(uri, "#{uri}/deep_path").should == true }
end
context 'otherwise' do
it do
util.uri_match?(uri, 'http://client.example.com/other').should == false
util.uri_match?(uri, 'http://attacker.example.com/callback').should == false
end
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/oauth2_spec.rb 0000644 0000041 0000041 00000004130 13410611536 021507 0 ustar www-data www-data require 'spec_helper'
describe Rack::OAuth2 do
subject { Rack::OAuth2 }
after { Rack::OAuth2.debugging = false }
its(:logger) { should be_a Logger }
its(:debugging?) { should == false }
describe '.debug!' do
before { Rack::OAuth2.debug! }
its(:debugging?) { should == true }
end
describe '.debug' do
it 'should enable debugging within given block' do
Rack::OAuth2.debug do
Rack::OAuth2.debugging?.should == true
end
Rack::OAuth2.debugging?.should == false
end
it 'should not force disable debugging' do
Rack::OAuth2.debug!
Rack::OAuth2.debug do
Rack::OAuth2.debugging?.should == true
end
Rack::OAuth2.debugging?.should == true
end
end
describe '.http_config' do
context 'when request_filter added' do
context 'when "debug!" is called' do
after { Rack::OAuth2.reset_http_config! }
it 'should put Debugger::RequestFilter at last' do
Rack::OAuth2.debug!
Rack::OAuth2.http_config do |config|
config.request_filter << Proc.new {}
end
Rack::OAuth2.http_client.request_filter.last.should be_instance_of Rack::OAuth2::Debugger::RequestFilter
end
it 'should reset_http_config' do
Rack::OAuth2.debug!
Rack::OAuth2.http_config do |config|
config.request_filter << Proc.new {}
end
size = Rack::OAuth2.http_client.request_filter.size
Rack::OAuth2.reset_http_config!
Rack::OAuth2.http_client.request_filter.size.should == size - 1
end
end
end
end
describe ".http_client" do
context "when local_http_config is used" do
it "should correctly set request_filter" do
clnt1 = Rack::OAuth2.http_client
clnt2 = Rack::OAuth2.http_client("my client") do |config|
config.request_filter << Proc.new {}
end
clnt3 = Rack::OAuth2.http_client
clnt1.request_filter.size.should == clnt3.request_filter.size
clnt1.request_filter.size.should == clnt2.request_filter.size - 1
end
end
end
end rack-oauth2-1.9.3/spec/rack/oauth2/access_token_spec.rb 0000644 0000041 0000041 00000004234 13410611536 022753 0 ustar www-data www-data require 'spec_helper'
describe Rack::OAuth2::AccessToken do
let :token do
Rack::OAuth2::AccessToken::Bearer.new(
access_token: 'access_token',
refresh_token: 'refresh_token',
expires_in: 3600,
scope: [:scope1, :scope2]
)
end
subject { token }
its(:access_token) { should == 'access_token' }
its(:refresh_token) { should == 'refresh_token' }
its(:expires_in) { should == 3600 }
its(:scope) { should == [:scope1, :scope2] }
its(:token_response) do
should == {
token_type: :bearer,
access_token: 'access_token',
refresh_token: 'refresh_token',
expires_in: 3600,
scope: 'scope1 scope2'
}
end
context 'when access_token is missing' do
it do
expect do
Rack::OAuth2::AccessToken::Bearer.new(
refresh_token: 'refresh_token',
expires_in: 3600,
scope: [:scope1, :scope2]
)
end.to raise_error AttrRequired::AttrMissing
end
end
context 'otherwise' do
it do
expect do
Rack::OAuth2::AccessToken::Bearer.new(
access_token: 'access_token'
)
end.not_to raise_error
end
end
let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
[:get, :delete, :post, :put].each do |method|
describe method do
it 'should delegate to HTTPClient with Authenticator filter' do
expect(token.httpclient).to receive(method).with(resource_endpoint)
token.httpclient.request_filter.last.should be_a Rack::OAuth2::AccessToken::Authenticator
token.send method, resource_endpoint
end
end
context 'in debug mode' do
it do
Rack::OAuth2.debug do
token.httpclient.request_filter[-2].should be_a Rack::OAuth2::AccessToken::Authenticator
token.httpclient.request_filter.last.should be_a Rack::OAuth2::Debugger::RequestFilter
end
end
end
context 'when extension params given' do
subject do
Rack::OAuth2::AccessToken::Bearer.new(
access_token: 'access_token',
ex_key: :ex_value
)
end
its(:raw_attributes) { should include :ex_key }
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/access_token/ 0000755 0000041 0000041 00000000000 13410611536 021411 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/access_token/mac/ 0000755 0000041 0000041 00000000000 13410611536 022151 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/access_token/mac/signature_spec.rb 0000644 0000041 0000041 00000003542 13410611536 025515 0 ustar www-data www-data require 'spec_helper'
describe Rack::OAuth2::AccessToken::MAC::Signature do
# From the example of Webtopay wallet API
# ref) https://www.webtopay.com/wallet/
context 'when ext is not given' do
subject do
Rack::OAuth2::AccessToken::MAC::Signature.new(
secret: 'IrdTc8uQodU7PRpLzzLTW6wqZAO6tAMU',
algorithm: 'hmac-sha-256',
nonce: 'dj83hs9s',
ts: 1336363200,
method: 'GET',
request_uri: '/wallet/rest/api/v1/payment/123',
host: 'www.webtopay.com',
port: 443
)
end
its(:calculate) { should == 'OZE9fTk2qiRtL1jb01L8lRxC66PTiAGhMDEmboeVeLs=' }
end
# From the example of MAC spec section 1.1
# ref) http://tools.ietf.org/pdf/draft-ietf-oauth-v2-http-mac-01.pdf
context 'when ext is not given' do
subject do
Rack::OAuth2::AccessToken::MAC::Signature.new(
secret: '489dks293j39',
algorithm: 'hmac-sha-1',
nonce: 'dj83hs9s',
ts: 1336363200,
method: 'GET',
request_uri: '/resource/1?b=1&a=2',
host: 'example.com',
port: 80
)
end
its(:calculate) { should == '6T3zZzy2Emppni6bzL7kdRxUWL4=' }
end
# From the example of MAC spec section 3.2
# ref) http://tools.ietf.org/pdf/draft-ietf-oauth-v2-http-mac-01.pdf
context 'otherwise' do
subject do
Rack::OAuth2::AccessToken::MAC::Signature.new(
secret: '489dks293j39',
algorithm: 'hmac-sha-1',
nonce: '7d8f3e4a',
ts: 264095,
method: 'POST',
request_uri: '/request?b5=%3D%253D&a3=a&c%40=&a2=r%20b&c2&a3=2+q',
host: 'example.com',
port: 80,
ext: 'a,b,c'
)
end
its(:calculate) { should == '+txL5oOFHGYjrfdNYH5VEzROaBY=' }
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/access_token/mac/verifier_spec.rb 0000644 0000041 0000041 00000001310 13410611536 025316 0 ustar www-data www-data require 'spec_helper'
describe Rack::OAuth2::AccessToken::MAC::Verifier do
let(:verifier) { Rack::OAuth2::AccessToken::MAC::Verifier.new(algorithm: algorithm) }
subject { verifier }
context 'when "hmac-sha-1" is specified' do
let(:algorithm) { 'hmac-sha-1' }
its(:hash_generator) { should be_instance_of OpenSSL::Digest::SHA1 }
end
context 'when "hmac-sha-256" is specified' do
let(:algorithm) { 'hmac-sha-256' }
its(:hash_generator) { should be_instance_of OpenSSL::Digest::SHA256 }
end
context 'otherwise' do
let(:algorithm) { 'invalid' }
it do
expect { verifier.send(:hash_generator) }.to raise_error(StandardError, 'Unsupported Algorithm')
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/access_token/mac/sha256_hex_verifier_spec.rb 0000644 0000041 0000041 00000001504 13410611536 027257 0 ustar www-data www-data require 'spec_helper'
describe Rack::OAuth2::AccessToken::MAC::Sha256HexVerifier do
# From the example of webtopay wallet API spec
# ref) https://www.webtopay.com/wallet/#authentication
context 'when example from webtopay wallet API' do
subject do
Rack::OAuth2::AccessToken::MAC::Sha256HexVerifier.new(
algorithm: 'hmac-sha-256',
raw_body: 'grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=http%3A%2F%2Flocalhost%2Fabc'
)
end
its(:calculate) { should == '21fb73c40b589622d0c78e9cd8900f89d9472aa724d0e5c3eca9ac1cd9d2a6d5' }
end
context 'when raw_body is empty' do
subject do
Rack::OAuth2::AccessToken::MAC::Sha256HexVerifier.new(
algorithm: 'hmac-sha-256',
raw_body: ''
)
end
its(:calculate) { should be_nil }
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/access_token/mac_spec.rb 0000644 0000041 0000041 00000011016 13410611536 023507 0 ustar www-data www-data require 'spec_helper'
describe Rack::OAuth2::AccessToken::MAC do
let(:ts) { 1305820234 }
let :token do
Rack::OAuth2::AccessToken::MAC.new(
access_token: 'access_token',
mac_key: 'secret',
mac_algorithm: 'hmac-sha-256',
ts: ts
)
end
let :token_with_ext_verifier do
Rack::OAuth2::AccessToken::MAC.new(
access_token: 'access_token',
mac_key: 'secret',
mac_algorithm: 'hmac-sha-256',
ts: ts,
ext_verifier: Rack::OAuth2::AccessToken::MAC::Sha256HexVerifier
)
end
let(:nonce) { '1000:51e74de734c05613f37520872e68db5f' }
let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
subject { token }
its(:mac_key) { should == 'secret' }
its(:mac_algorithm) { should == 'hmac-sha-256' }
its(:token_response) do
should == {
access_token: 'access_token',
refresh_token: nil,
token_type: :mac,
expires_in: nil,
scope: '',
mac_key: 'secret',
mac_algorithm: 'hmac-sha-256'
}
end
its(:generate_nonce) { should be_a String }
describe 'verify!' do
let(:request) { Rack::OAuth2::Server::Resource::MAC::Request.new(env) }
context 'when no ext_verifier is given' do
let(:env) do
Rack::MockRequest.env_for(
'/protected_resources',
'HTTP_AUTHORIZATION' => %{MAC id="access_token", nonce="#{nonce}", ts="#{ts}" mac="#{signature}"}
)
end
context 'when signature is valid' do
let(:signature) { 'BgooS/voPOZWLwoVfx4+zbC3xAVKW3jtjhKYOfIGZOA=' }
it do
token.verify!(request.setup!).should == :verified
end
end
context 'otherwise' do
let(:signature) { 'invalid' }
it do
expect { token.verify!(request.setup!) }.to raise_error(
Rack::OAuth2::Server::Resource::MAC::Unauthorized,
'invalid_token :: Signature Invalid'
)
end
end
end
context 'when ext_verifier is given' do
let(:env) do
Rack::MockRequest.env_for(
'/protected_resources',
method: :POST,
params: {
key1: 'value1'
},
'HTTP_AUTHORIZATION' => %{MAC id="access_token", nonce="#{nonce}", ts="#{ts}", mac="#{signature}", ext="#{ext}"}
)
end
let(:signature) { 'invalid' }
context 'when ext is invalid' do
let(:ext) { 'invalid' }
it do
expect { token_with_ext_verifier.verify!(request.setup!) }.to raise_error(
Rack::OAuth2::Server::Resource::MAC::Unauthorized,
'invalid_token :: Sha256HexVerifier Invalid'
)
end
end
context 'when ext is valid' do
let(:ext) { '4cfcd46c59f54b5ea6a5f9b05c28b52fef2864747194b5fdfc3d59c0057bf35a' }
context 'when signature is valid' do
let(:signature) { 'dZYR54n+Lym5qCRRmDqmRZ71rG+bkjSWmqrOv8OjYHk=' }
it do
Time.fix(Time.at(1302361200)) do
token_with_ext_verifier.verify!(request.setup!).should == :verified
end
end
end
context 'otherwise' do
it do
expect { token.verify!(request.setup!) }.to raise_error(
Rack::OAuth2::Server::Resource::MAC::Unauthorized,
'invalid_token :: Signature Invalid'
)
end
end
end
end
end
describe '.authenticate' do
let(:request) { HTTPClient.new.send(:create_request, :post, URI.parse(resource_endpoint), {}, {hello: "world"}, {}) }
context 'when no ext_verifier is given' do
let(:signature) { 'pOBaL6HRawe4tUPmcU4vJEj1f2GJqrbQOlCcdAYgI/s=' }
it 'should set Authorization header' do
expect(token).to receive(:generate_nonce).and_return(nonce)
expect(request.header).to receive(:[]=).with('Authorization', "MAC id=\"access_token\", nonce=\"#{nonce}\", ts=\"#{ts.to_i}\", mac=\"#{signature}\"")
token.authenticate(request)
end
end
context 'when ext_verifier is given' do
let(:signature) { 'vgU0fj6rSpwUCAoCOrXlu8pZBR8a5Q5xIVlB4MCvJeM=' }
let(:ext) { '3d011e09502a84552a0f8ae112d024cc2c115597e3a577d5f49007902c221dc5' }
it 'should set Authorization header with ext_verifier' do
expect(token_with_ext_verifier).to receive(:generate_nonce).and_return(nonce)
expect(request.header).to receive(:[]=).with('Authorization', "MAC id=\"access_token\", nonce=\"#{nonce}\", ts=\"#{ts.to_i}\", mac=\"#{signature}\", ext=\"#{ext}\"")
token_with_ext_verifier.authenticate(request)
end
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/access_token/authenticator_spec.rb 0000644 0000041 0000041 00000002252 13410611536 025623 0 ustar www-data www-data require 'spec_helper'
describe Rack::OAuth2::AccessToken::Authenticator do
let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
let(:request) { HTTP::Message.new_request(:get, URI.parse(resource_endpoint)) }
let(:authenticator) { Rack::OAuth2::AccessToken::Authenticator.new(token) }
shared_examples_for :authenticator do
it 'should let the token authenticate the request' do
expect(token).to receive(:authenticate).with(request)
authenticator.filter_request(request)
end
end
context 'when Legacy token is given' do
let(:token) do
Rack::OAuth2::AccessToken::Legacy.new(
access_token: 'access_token'
)
end
it_behaves_like :authenticator
end
context 'when Bearer token is given' do
let(:token) do
Rack::OAuth2::AccessToken::Bearer.new(
access_token: 'access_token'
)
end
it_behaves_like :authenticator
end
context 'when MAC token is given' do
let(:token) do
Rack::OAuth2::AccessToken::MAC.new(
access_token: 'access_token',
mac_key: 'secret',
mac_algorithm: 'hmac-sha-256'
)
end
it_behaves_like :authenticator
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/access_token/bearer_spec.rb 0000644 0000041 0000041 00000001113 13410611536 024204 0 ustar www-data www-data require 'spec_helper'
describe Rack::OAuth2::AccessToken::Bearer do
let :token do
Rack::OAuth2::AccessToken::Bearer.new(
access_token: 'access_token'
)
end
let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
let(:request) { HTTPClient.new.send(:create_request, :post, URI.parse(resource_endpoint), {}, {hello: "world"}, {}) }
describe '.authenticate' do
it 'should set Authorization header' do
expect(request.header).to receive(:[]=).with('Authorization', 'Bearer access_token')
token.authenticate(request)
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/access_token/legacy_spec.rb 0000644 0000041 0000041 00000001255 13410611536 024217 0 ustar www-data www-data require 'spec_helper'
describe Rack::OAuth2::AccessToken::Legacy do
let :token do
Rack::OAuth2::AccessToken::Legacy.new(
access_token: 'access_token'
)
end
let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
let(:request) { HTTPClient.new.send(:create_request, :post, URI.parse(resource_endpoint), {}, {hello: "world"}, {}) }
describe '#to_s' do
subject { token }
its(:to_s) { should == token.access_token }
end
describe '.authenticate' do
it 'should set Authorization header' do
expect(request.header).to receive(:[]=).with('Authorization', 'OAuth access_token')
token.authenticate(request)
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/client_spec.rb 0000644 0000041 0000041 00000033671 13410611536 021577 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Client do
let :client do
Rack::OAuth2::Client.new(
identifier: 'client_id',
secret: 'client_secret',
host: 'server.example.com',
redirect_uri: 'https://client.example.com/callback'
)
end
subject { client }
its(:identifier) { should == 'client_id' }
its(:secret) { should == 'client_secret' }
its(:authorization_endpoint) { should == '/oauth2/authorize' }
its(:token_endpoint) { should == '/oauth2/token' }
context 'when identifier is missing' do
it do
expect { Rack::OAuth2::Client.new }.to raise_error AttrRequired::AttrMissing
end
end
describe '#authorization_uri' do
subject { client.authorization_uri }
it { should include 'https://server.example.com/oauth2/authorize' }
it { should include 'client_id=client_id' }
it { should include 'redirect_uri=https%3A%2F%2Fclient.example.com%2Fcallback' }
it { should include 'response_type=code' }
context 'when endpoints are absolute URIs' do
before do
client.authorization_endpoint = 'https://server2.example.com/oauth/authorize'
client.token_endpoint = 'https://server2.example.com/oauth/token'
end
it { should include 'https://server2.example.com/oauth/authorize' }
end
context 'when scheme is specified' do
before { client.scheme = 'http' }
it { should include 'http://server.example.com/oauth2/authorize' }
end
context 'when response_type is token' do
subject { client.authorization_uri(response_type: :token) }
it { should include 'response_type=token' }
end
context 'when response_type is an Array' do
subject { client.authorization_uri(response_type: [:token, :code]) }
it { should include 'response_type=token+code' }
end
context 'when scope is given' do
subject { client.authorization_uri(scope: [:scope1, :scope2]) }
it { should include 'scope=scope1+scope2' }
end
end
describe '#authorization_code=' do
before { client.authorization_code = 'code' }
subject { client.instance_variable_get('@grant') }
it { should be_instance_of Rack::OAuth2::Client::Grant::AuthorizationCode }
end
describe '#resource_owner_credentials=' do
before { client.resource_owner_credentials = 'username', 'password' }
subject { client.instance_variable_get('@grant') }
it { should be_instance_of Rack::OAuth2::Client::Grant::Password }
end
describe '#refresh_token=' do
before { client.refresh_token = 'refresh_token' }
subject { client.instance_variable_get('@grant') }
it { should be_instance_of Rack::OAuth2::Client::Grant::RefreshToken }
end
describe '#access_token!' do
subject { client.access_token! }
context '*args handling' do
describe 'client authentication method' do
before do
client.authorization_code = 'code'
end
it 'should be Basic auth as default' do
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/bearer.json',
request_header: {
'Authorization' => 'Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ='
}
)
client.access_token!
end
context 'when jwt_bearer auth method specified' do
context 'when client_secret is given' do
it 'should be JWT bearer client assertion w/ auto-generated HS256-signed JWT assertion' do
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/bearer.json',
params: {
client_assertion: /^eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9\..+/, # NOTE: HS256
client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
code: 'code',
grant_type: 'authorization_code',
redirect_uri: 'https://client.example.com/callback'
}
)
client.access_token! :jwt_bearer
end
end
context 'when private_key is given' do
context 'when RSA key' do
let :client do
Rack::OAuth2::Client.new(
identifier: 'client_id',
private_key: OpenSSL::PKey::RSA.generate(2048),
host: 'server.example.com',
redirect_uri: 'https://client.example.com/callback'
)
end
it 'should be JWT bearer client assertion w/ auto-generated RS256-signed JWT assertion' do
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/bearer.json',
params: {
client_assertion: /^eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9\..+/, # NOTE: RS256
client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
code: 'code',
grant_type: 'authorization_code',
redirect_uri: 'https://client.example.com/callback'
}
)
client.access_token! :jwt_bearer
end
end
context 'when EC key' do
let :client do
Rack::OAuth2::Client.new(
identifier: 'client_id',
private_key: OpenSSL::PKey::EC.new('prime256v1').generate_key,
host: 'server.example.com',
redirect_uri: 'https://client.example.com/callback'
)
end
it 'should be JWT bearer client assertion w/ auto-generated ES256-signed JWT assertion' do
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/bearer.json',
params: {
client_assertion: /^eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9\..+/, # NOTE: ES256
client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
code: 'code',
grant_type: 'authorization_code',
redirect_uri: 'https://client.example.com/callback'
}
)
client.access_token! :jwt_bearer
end
end
end
context 'when client_assertion is explicitly given' do
let :client do
Rack::OAuth2::Client.new(
identifier: 'client_id',
host: 'server.example.com',
redirect_uri: 'https://client.example.com/callback'
)
end
it 'should be JWT bearer client assertion w/ specified assertion' do
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/bearer.json',
params: {
client_assertion: 'any.jwt.assertion',
client_assertion_type: Rack::OAuth2::URN::ClientAssertionType::JWT_BEARER,
code: 'code',
grant_type: 'authorization_code',
redirect_uri: 'https://client.example.com/callback'
}
)
client.access_token! :jwt_bearer, client_assertion: 'any.jwt.assertion'
end
end
end
context 'when other auth method specified' do
it 'should be body params' do
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/bearer.json',
params: {
client_id: 'client_id',
client_secret: 'client_secret',
code: 'code',
grant_type: 'authorization_code',
redirect_uri: 'https://client.example.com/callback'
}
)
client.access_token! :client_auth_body
end
end
context 'when auth method is specified as Hash' do
it 'should be removed before sending request' do
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/bearer.json',
params: {
client_id: 'client_id',
client_secret: 'client_secret',
code: 'code',
grant_type: 'authorization_code',
redirect_uri: 'https://client.example.com/callback'
}
)
client.access_token! client_auth_method: :body
end
end
end
describe 'scopes' do
context 'when scope option given' do
it 'should specify given scope' do
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/bearer.json',
params: {
grant_type: 'client_credentials',
scope: 'a b'
}
)
client.access_token! scope: [:a, :b]
end
end
end
describe 'unknown params' do
it 'should be included in body params' do
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/bearer.json',
params: {
grant_type: 'client_credentials',
resource: 'something'
}
)
client.access_token! resource: :something
end
end
end
context 'when bearer token is given' do
before do
client.authorization_code = 'code'
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/bearer.json'
)
end
it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
its(:token_type) { should == :bearer }
its(:access_token) { should == 'access_token' }
its(:refresh_token) { should == 'refresh_token' }
its(:expires_in) { should == 3600 }
context 'when token type is "Bearer", not "bearer"' do
before do
client.authorization_code = 'code'
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/_Bearer.json'
)
end
it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
its(:token_type) { should == :bearer }
end
end
context 'when mac token is given' do
before do
client.authorization_code = 'code'
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/mac.json'
)
end
it { should be_instance_of Rack::OAuth2::AccessToken::MAC }
its(:token_type) { should == :mac }
its(:access_token) { should == 'access_token' }
its(:refresh_token) { should == 'refresh_token' }
its(:expires_in) { should == 3600 }
end
context 'when no-type token is given (JSON)' do
before do
client.authorization_code = 'code'
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/legacy.json'
)
end
it { should be_instance_of Rack::OAuth2::AccessToken::Legacy }
its(:token_type) { should == :legacy }
its(:access_token) { should == 'access_token' }
its(:refresh_token) { should == 'refresh_token' }
its(:expires_in) { should == 3600 }
context 'when token_type is forced' do
before do
client.force_token_type! :bearer
end
it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
its(:token_type) { should == :bearer }
end
end
context 'when no-type token is given (key-value)' do
before do
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/legacy.txt'
)
end
it { should be_instance_of Rack::OAuth2::AccessToken::Legacy }
its(:token_type) { should == :legacy }
its(:access_token) { should == 'access_token' }
its(:expires_in) { should == 3600 }
context 'when expires_in is not given' do
before do
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/legacy_without_expires_in.txt'
)
end
its(:expires_in) { should be_nil }
end
end
context 'when unknown-type token is given' do
before do
client.authorization_code = 'code'
mock_response(
:post,
'https://server.example.com/oauth2/token',
'tokens/unknown.json'
)
end
it do
expect { client.access_token! }.to raise_error(StandardError, 'Unknown Token Type')
end
end
context 'when error response is given' do
before do
mock_response(
:post,
'https://server.example.com/oauth2/token',
'errors/invalid_request.json',
status: 400
)
end
it do
expect { client.access_token! }.to raise_error Rack::OAuth2::Client::Error
end
end
context 'when no body given' do
context 'when error given' do
before do
mock_response(
:post,
'https://server.example.com/oauth2/token',
'blank',
status: 400
)
end
it do
expect { client.access_token! }.to raise_error Rack::OAuth2::Client::Error
end
end
end
end
context 'when no host info' do
let :client do
Rack::OAuth2::Client.new(
identifier: 'client_id',
secret: 'client_secret',
redirect_uri: 'https://client.example.com/callback'
)
end
describe '#authorization_uri' do
it do
expect { client.authorization_uri }.to raise_error 'No Host Info'
end
end
describe '#access_token!' do
it do
expect { client.access_token! }.to raise_error 'No Host Info'
end
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/ 0000755 0000041 0000041 00000000000 13410611536 020256 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/server/token_spec.rb 0000644 0000041 0000041 00000007405 13410611536 022743 0 ustar www-data www-data require 'spec_helper.rb'
require 'base64'
describe Rack::OAuth2::Server::Token do
let(:request) { Rack::MockRequest.new app }
let(:app) do
Rack::OAuth2::Server::Token.new do |request, response|
response.access_token = Rack::OAuth2::AccessToken::Bearer.new(access_token: 'access_token')
end
end
let(:params) do
{
grant_type: 'authorization_code',
client_id: 'client_id',
code: 'authorization_code',
redirect_uri: 'http://client.example.com/callback'
}
end
subject { request.post('/token', params: params) }
context 'when multiple client credentials are given' do
context 'when different credentials are given' do
let(:env) do
Rack::MockRequest.env_for(
'/token',
'HTTP_AUTHORIZATION' => "Basic #{Base64.encode64('client_id2:client_secret')}",
params: params
)
end
it 'should fail with unsupported_grant_type' do
status, header, response = app.call(env)
status.should == 400
response.body.first.should include '"error":"invalid_request"'
end
end
context 'when same credentials are given' do
let(:env) do
Rack::MockRequest.env_for(
'/token',
'HTTP_AUTHORIZATION' => "Basic #{Base64.encode64('client_id:client_secret')}",
params: params
)
end
it 'should ignore duplicates' do
status, header, response = app.call(env)
status.should == 200
end
end
end
context 'when unsupported grant_type is given' do
before do
params.merge!(grant_type: 'unknown')
end
its(:status) { should == 400 }
its(:content_type) { should == 'application/json' }
its(:body) { should include '"error":"unsupported_grant_type"' }
end
[:client_id, :grant_type].each do |required|
context "when #{required} is missing" do
before do
params.delete_if do |key, value|
key == required
end
end
its(:status) { should == 400 }
its(:content_type) { should == 'application/json' }
its(:body) { should include '"error":"invalid_request"' }
end
end
Rack::OAuth2::Server::Token::ErrorMethods::DEFAULT_DESCRIPTION.each do |error, default_message|
status = if error == :invalid_client
401
else
400
end
context "when #{error}" do
let(:app) do
Rack::OAuth2::Server::Token.new do |request, response|
request.send "#{error}!"
end
end
its(:status) { should == status }
its(:content_type) { should == 'application/json' }
its(:body) { should include "\"error\":\"#{error}\"" }
its(:body) { should include "\"error_description\":\"#{default_message}\"" }
end
end
context 'when responding' do
context 'when access_token is missing' do
let(:app) do
Rack::OAuth2::Server::Token.new
end
it do
expect { request.post('/', params: params) }.to raise_error AttrRequired::AttrMissing
end
end
end
describe 'extensibility' do
before do
require 'rack/oauth2/server/token/extension/example'
end
subject { app }
let(:env) do
Rack::MockRequest.env_for(
'/token',
params: params
)
end
let(:request) { Rack::OAuth2::Server::Token::Request.new env }
its(:extensions) { should == [Rack::OAuth2::Server::Token::Extension::Example] }
describe 'JWT assertion' do
let(:params) do
{
grant_type: 'urn:ietf:params:oauth:grant-type:example',
assertion: 'header.payload.signature'
}
end
it do
app.send(
:grant_type_for, request
).should == Rack::OAuth2::Server::Token::Extension::Example
end
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/authorize/ 0000755 0000041 0000041 00000000000 13410611536 022270 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/server/authorize/token_spec.rb 0000644 0000041 0000041 00000004577 13410611536 024764 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Authorize::Token do
let(:request) { Rack::MockRequest.new app }
let(:redirect_uri) { 'http://client.example.com/callback' }
let(:access_token) { 'access_token' }
let(:response) { request.get("/?response_type=token&client_id=client&redirect_uri=#{redirect_uri}&state=state") }
context "when approved" do
subject { response }
let(:bearer_token) { Rack::OAuth2::AccessToken::Bearer.new(access_token: access_token) }
let :app do
Rack::OAuth2::Server::Authorize.new do |request, response|
response.redirect_uri = redirect_uri
response.access_token = bearer_token
response.approve!
end
end
its(:status) { should == 302 }
its(:location) { should == "#{redirect_uri}#access_token=#{access_token}&state=state&token_type=bearer" }
context 'when refresh_token is given' do
let :bearer_token do
Rack::OAuth2::AccessToken::Bearer.new(
access_token: access_token,
refresh_token: 'refresh'
)
end
its(:location) { should == "#{redirect_uri}#access_token=#{access_token}&state=state&token_type=bearer" }
end
context 'when redirect_uri is missing' do
let :app do
Rack::OAuth2::Server::Authorize.new do |request, response|
response.access_token = bearer_token
response.approve!
end
end
it do
expect { response }.to raise_error AttrRequired::AttrMissing
end
end
context 'when access_token is missing' do
let :app do
Rack::OAuth2::Server::Authorize.new do |request, response|
response.redirect_uri = redirect_uri
response.approve!
end
end
it do
expect { response }.to raise_error AttrRequired::AttrMissing
end
end
end
context 'when denied' do
let :app do
Rack::OAuth2::Server::Authorize.new do |request, response|
request.verify_redirect_uri! redirect_uri
request.access_denied!
end
end
it 'should redirect with error in fragment' do
response.status.should == 302
error_message = {
error: :access_denied,
error_description: Rack::OAuth2::Server::Authorize::ErrorMethods::DEFAULT_DESCRIPTION[:access_denied]
}
response.location.should == "#{redirect_uri}##{error_message.to_query}&state=state"
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/authorize/error_spec.rb 0000644 0000041 0000041 00000007437 13410611536 024773 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Authorize::BadRequest do
let(:klass) { Rack::OAuth2::Server::Authorize::BadRequest }
let(:error) { klass.new(:invalid_request) }
let(:redirect_uri) { 'http://client.example.com/callback' }
subject { error }
it { should be_a Rack::OAuth2::Server::Abstract::BadRequest }
its(:protocol_params) do
should == {
error: :invalid_request,
error_description: nil,
error_uri: nil,
state: nil
}
end
describe '#finish' do
context 'when redirect_uri is given' do
before { error.redirect_uri = redirect_uri }
context 'when protocol_params_location = :query' do
before { error.protocol_params_location = :query }
it 'should redirect with error in query' do
state, header, response = error.finish
state.should == 302
header["Location"].should == "#{redirect_uri}?error=invalid_request"
end
end
context 'when protocol_params_location = :fragment' do
before { error.protocol_params_location = :fragment }
it 'should redirect with error in fragment' do
state, header, response = error.finish
state.should == 302
header["Location"].should == "#{redirect_uri}#error=invalid_request"
end
end
context 'otherwise' do
before { error.protocol_params_location = :other }
it 'should redirect without error' do
state, header, response = error.finish
state.should == 302
header["Location"].should == redirect_uri
end
end
end
context 'otherwise' do
it 'should raise itself' do
expect { error.finish }.to raise_error(klass) { |e|
e.should == error
}
end
end
end
end
describe Rack::OAuth2::Server::Authorize::ErrorMethods do
let(:klass) { Rack::OAuth2::Server::Authorize::BadRequest }
let(:redirect_uri) { 'http://client.example.com/callback' }
let(:default_description) { Rack::OAuth2::Server::Authorize::ErrorMethods::DEFAULT_DESCRIPTION }
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client_id") }
let(:request) { Rack::OAuth2::Server::Authorize::Request.new env }
let(:request_for_code) { Rack::OAuth2::Server::Authorize::Code::Request.new env }
let(:request_for_token) { Rack::OAuth2::Server::Authorize::Token::Request.new env }
describe 'bad_request!' do
it do
expect { request.bad_request! }.to raise_error klass
end
context 'when response_type = :code' do
it 'should set protocol_params_location = :query' do
expect { request_for_code.bad_request! }.to raise_error(klass) { |e|
e.protocol_params_location.should == :query
}
end
end
context 'when response_type = :token' do
it 'should set protocol_params_location = :fragment' do
expect { request_for_token.bad_request! }.to raise_error(klass) { |e|
e.protocol_params_location.should == :fragment
}
end
end
end
Rack::OAuth2::Server::Authorize::ErrorMethods::DEFAULT_DESCRIPTION.keys.each do |error_code|
method = "#{error_code}!"
klass = case error_code
when :server_error
Rack::OAuth2::Server::Authorize::ServerError
when :temporarily_unavailable
Rack::OAuth2::Server::Authorize::TemporarilyUnavailable
else
Rack::OAuth2::Server::Authorize::BadRequest
end
describe method do
it "should raise #{klass} with error = :#{error_code}" do
klass =
expect { request.send method }.to raise_error(klass) { |error|
error.error.should == error_code
error.description.should == default_description[error_code]
}
end
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/authorize/code_spec.rb 0000644 0000041 0000041 00000003624 13410611536 024546 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Authorize::Code do
let(:request) { Rack::MockRequest.new app }
let(:redirect_uri) { 'http://client.example.com/callback' }
let(:authorization_code) { 'authorization_code' }
let(:response) { request.get "/?response_type=code&client_id=client&redirect_uri=#{redirect_uri}&state=state" }
context 'when approved' do
subject { response }
let :app do
Rack::OAuth2::Server::Authorize.new do |request, response|
response.redirect_uri = redirect_uri
response.code = authorization_code
response.approve!
end
end
its(:status) { should == 302 }
its(:location) { should == "#{redirect_uri}?code=#{authorization_code}&state=state" }
context 'when redirect_uri already includes query' do
let(:redirect_uri) { 'http://client.example.com/callback?k=v' }
its(:location) { should == "#{redirect_uri}&code=#{authorization_code}&state=state" }
end
context 'when redirect_uri is missing' do
let(:redirect_uri) { nil }
it do
expect { response }.to raise_error AttrRequired::AttrMissing
end
end
context 'when code is missing' do
let(:authorization_code) { nil }
it do
expect { response }.to raise_error AttrRequired::AttrMissing
end
end
end
context 'when denied' do
let :app do
Rack::OAuth2::Server::Authorize.new do |request, response|
request.verify_redirect_uri! redirect_uri
request.access_denied!
end
end
it 'should redirect with error in query' do
response.status.should == 302
error_message = {
error: :access_denied,
error_description: Rack::OAuth2::Server::Authorize::ErrorMethods::DEFAULT_DESCRIPTION[:access_denied]
}
response.location.should == "#{redirect_uri}?#{error_message.to_query}&state=state"
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/authorize/extensions/ 0000755 0000041 0000041 00000000000 13410611536 024467 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/server/authorize/extensions/code_and_token_spec.rb 0000644 0000041 0000041 00000004312 13410611536 030762 0 ustar www-data www-data require 'spec_helper.rb'
require 'rack/oauth2/server/authorize/extension/code_and_token'
describe Rack::OAuth2::Server::Authorize::Extension::CodeAndToken do
let(:request) { Rack::MockRequest.new app }
let(:redirect_uri) { 'http://client.example.com/callback' }
let(:access_token) { 'access_token' }
let(:authorization_code) { 'authorization_code' }
let(:response) do
request.get("/?response_type=code%20token&client_id=client&redirect_uri=#{redirect_uri}")
end
context "when approved" do
subject { response }
let(:bearer_token) { Rack::OAuth2::AccessToken::Bearer.new(access_token: access_token) }
let :app do
Rack::OAuth2::Server::Authorize.new do |request, response|
response.redirect_uri = redirect_uri
response.access_token = bearer_token
response.code = authorization_code
response.approve!
end
end
its(:status) { should == 302 }
its(:location) { should include "#{redirect_uri}#" }
its(:location) { should include "code=#{authorization_code}"}
its(:location) { should include "access_token=#{access_token}"}
its(:location) { should include 'token_type=bearer' }
context 'when refresh_token is given' do
let :bearer_token do
Rack::OAuth2::AccessToken::Bearer.new(
access_token: access_token,
refresh_token: 'refresh'
)
end
its(:location) { should include "#{redirect_uri}#" }
its(:location) { should include "code=#{authorization_code}"}
its(:location) { should include "access_token=#{access_token}"}
its(:location) { should include 'token_type=bearer' }
end
end
context 'when denied' do
let :app do
Rack::OAuth2::Server::Authorize.new do |request, response|
request.verify_redirect_uri! redirect_uri
request.access_denied!
end
end
it 'should redirect with error in fragment' do
response.status.should == 302
error_message = {
error: :access_denied,
error_description: Rack::OAuth2::Server::Authorize::ErrorMethods::DEFAULT_DESCRIPTION[:access_denied]
}
response.location.should == "#{redirect_uri}##{error_message.to_query}"
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/abstract/ 0000755 0000041 0000041 00000000000 13410611536 022061 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/server/abstract/error_spec.rb 0000644 0000041 0000041 00000003306 13410611536 024553 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Abstract::Error do
context 'when full attributes are given' do
subject do
Rack::OAuth2::Server::Abstract::Error.new 400, :invalid_request, 'Missing some required params', uri: 'http://server.example.com/error'
end
its(:status) { should == 400 }
its(:error) { should == :invalid_request }
its(:description) { should == 'Missing some required params' }
its(:uri) { should == 'http://server.example.com/error' }
its(:protocol_params) do
should == {
error: :invalid_request,
error_description: 'Missing some required params',
error_uri: 'http://server.example.com/error'
}
end
end
context 'when optional attributes are not given' do
subject do
Rack::OAuth2::Server::Abstract::Error.new 400, :invalid_request
end
its(:status) { should == 400 }
its(:error) { should == :invalid_request }
its(:description) { should be_nil }
its(:uri) { should be_nil }
its(:protocol_params) do
should == {
error: :invalid_request,
error_description: nil,
error_uri: nil
}
end
end
end
describe Rack::OAuth2::Server::Abstract::BadRequest do
its(:status) { should == 400 }
end
describe Rack::OAuth2::Server::Abstract::Unauthorized do
its(:status) { should == 401 }
end
describe Rack::OAuth2::Server::Abstract::Forbidden do
its(:status) { should == 403 }
end
describe Rack::OAuth2::Server::Abstract::ServerError do
its(:status) { should == 500 }
end
describe Rack::OAuth2::Server::Abstract::TemporarilyUnavailable do
its(:status) { should == 503 }
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/token/ 0000755 0000041 0000041 00000000000 13410611536 021376 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/server/token/client_credentials_spec.rb 0000644 0000041 0000041 00000001346 13410611536 026574 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Token::ClientCredentials do
let(:request) { Rack::MockRequest.new app }
let(:app) do
Rack::OAuth2::Server::Token.new do |request, response|
response.access_token = Rack::OAuth2::AccessToken::Bearer.new(access_token: 'access_token')
end
end
let(:params) do
{
grant_type: 'client_credentials',
client_id: 'client_id',
client_secret: 'client_secret'
}
end
subject { request.post('/', params: params) }
its(:status) { should == 200 }
its(:content_type) { should == 'application/json' }
its(:body) { should include '"access_token":"access_token"' }
its(:body) { should include '"token_type":"bearer"' }
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/token/password_spec.rb 0000644 0000041 0000041 00000002134 13410611536 024577 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Token::Password do
let(:request) { Rack::MockRequest.new app }
let(:app) do
Rack::OAuth2::Server::Token.new do |request, response|
response.access_token = Rack::OAuth2::AccessToken::Bearer.new(access_token: 'access_token')
end
end
let(:params) do
{
grant_type: 'password',
client_id: 'client_id',
username: 'nov',
password: 'secret'
}
end
subject { request.post('/', params: params) }
its(:status) { should == 200 }
its(:content_type) { should == 'application/json' }
its(:body) { should include '"access_token":"access_token"' }
its(:body) { should include '"token_type":"bearer"' }
[:username, :password].each do |required|
context "when #{required} is missing" do
before do
params.delete_if do |key, value|
key == required
end
end
its(:status) { should == 400 }
its(:content_type) { should == 'application/json' }
its(:body) { should include '"error":"invalid_request"' }
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/token/jwt_bearer_spec.rb 0000644 0000041 0000041 00000002066 13410611536 025065 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Token::JWTBearer do
let(:request) { Rack::MockRequest.new app }
let(:app) do
Rack::OAuth2::Server::Token.new do |request, response|
response.access_token = Rack::OAuth2::AccessToken::Bearer.new(access_token: 'access_token')
end
end
let(:params) do
{
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
client_id: 'client_id',
assertion: 'header.payload.signature'
}
end
subject { request.post('/', params: params) }
its(:status) { should == 200 }
its(:content_type) { should == 'application/json' }
its(:body) { should include '"access_token":"access_token"' }
its(:body) { should include '"token_type":"bearer"' }
context 'when assertion is missing' do
before do
params.delete_if do |key, value|
key == :assertion
end
end
its(:status) { should == 400 }
its(:content_type) { should == 'application/json' }
its(:body) { should include '"error":"invalid_request"' }
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/token/authorization_code_spec.rb 0000644 0000041 0000041 00000002503 13410611536 026627 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Token::AuthorizationCode do
let(:request) { Rack::MockRequest.new app }
let(:app) do
Rack::OAuth2::Server::Token.new do |request, response|
response.access_token = Rack::OAuth2::AccessToken::Bearer.new(access_token: 'access_token')
end
end
let(:params) do
{
grant_type: 'authorization_code',
client_id: 'client_id',
code: 'authorization_code',
redirect_uri: 'http://client.example.com/callback'
}
end
let(:response) { request.post('/', params: params) }
subject { response }
its(:status) { should == 200 }
its(:content_type) { should == 'application/json' }
its(:body) { should include '"access_token":"access_token"' }
its(:body) { should include '"token_type":"bearer"' }
it 'should prevent to be cached' do
response.header['Cache-Control'].should == 'no-store'
response.header['Pragma'].should == 'no-cache'
end
[:code].each do |required|
context "when #{required} is missing" do
before do
params.delete_if do |key, value|
key == required
end
end
its(:status) { should == 400 }
its(:content_type) { should == 'application/json' }
its(:body) { should include '"error":"invalid_request"' }
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/token/saml2_bearer_spec.rb 0000644 0000041 0000041 00000002060 13410611536 025271 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Token::SAML2Bearer do
let(:request) { Rack::MockRequest.new app }
let(:app) do
Rack::OAuth2::Server::Token.new do |request, response|
response.access_token = Rack::OAuth2::AccessToken::Bearer.new(access_token: 'access_token')
end
end
let(:params) do
{
grant_type: 'urn:ietf:params:oauth:grant-type:saml2-bearer',
client_id: 'client_id',
assertion: '...'
}
end
subject { request.post('/', params: params) }
its(:status) { should == 200 }
its(:content_type) { should == 'application/json' }
its(:body) { should include '"access_token":"access_token"' }
its(:body) { should include '"token_type":"bearer"' }
context 'when assertion is missing' do
before do
params.delete_if do |key, value|
key == :assertion
end
end
its(:status) { should == 400 }
its(:content_type) { should == 'application/json' }
its(:body) { should include '"error":"invalid_request"' }
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/token/error_spec.rb 0000644 0000041 0000041 00000005322 13410611536 024070 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Token::BadRequest do
let(:error) { Rack::OAuth2::Server::Token::BadRequest.new(:invalid_request) }
it { should be_a Rack::OAuth2::Server::Abstract::BadRequest }
describe '#finish' do
it 'should respond in JSON' do
status, header, response = error.finish
status.should == 400
header['Content-Type'].should == 'application/json'
response.body.should == ['{"error":"invalid_request"}']
end
end
end
describe Rack::OAuth2::Server::Token::Unauthorized do
let(:error) { Rack::OAuth2::Server::Token::Unauthorized.new(:invalid_request) }
it { should be_a Rack::OAuth2::Server::Abstract::Unauthorized }
describe '#finish' do
it 'should respond in JSON' do
status, header, response = error.finish
status.should == 401
header['Content-Type'].should == 'application/json'
header['WWW-Authenticate'].should == 'Basic realm="OAuth2 Token Endpoint"'
response.body.should == ['{"error":"invalid_request"}']
end
end
end
describe Rack::OAuth2::Server::Token::ErrorMethods do
let(:bad_request) { Rack::OAuth2::Server::Token::BadRequest }
let(:unauthorized) { Rack::OAuth2::Server::Token::Unauthorized }
let(:redirect_uri) { 'http://client.example.com/callback' }
let(:default_description) { Rack::OAuth2::Server::Token::ErrorMethods::DEFAULT_DESCRIPTION }
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client_id") }
let(:request) { Rack::OAuth2::Server::Token::Request.new env }
describe 'bad_request!' do
it do
expect { request.bad_request! :invalid_request }.to raise_error bad_request
end
end
describe 'unauthorized!' do
it do
expect { request.unauthorized! :invalid_client }.to raise_error unauthorized
end
end
Rack::OAuth2::Server::Token::ErrorMethods::DEFAULT_DESCRIPTION.keys.each do |error_code|
method = "#{error_code}!"
case error_code
when :invalid_client
describe method do
it "should raise Rack::OAuth2::Server::Token::Unauthorized with error = :#{error_code}" do
expect { request.send method }.to raise_error(unauthorized) { |error|
error.error.should == error_code
error.description.should == default_description[error_code]
}
end
end
else
describe method do
it "should raise Rack::OAuth2::Server::Token::BadRequest with error = :#{error_code}" do
expect { request.send method }.to raise_error(bad_request) { |error|
error.error.should == error_code
error.description.should == default_description[error_code]
}
end
end
end
end
end rack-oauth2-1.9.3/spec/rack/oauth2/server/token/refresh_token_spec.rb 0000644 0000041 0000041 00000002034 13410611536 025572 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Token::RefreshToken do
let(:request) { Rack::MockRequest.new app }
let(:app) do
Rack::OAuth2::Server::Token.new do |request, response|
response.access_token = Rack::OAuth2::AccessToken::Bearer.new(access_token: 'access_token')
end
end
let(:params) do
{
grant_type: "refresh_token",
client_id: "client_id",
refresh_token: "refresh_token"
}
end
subject { request.post('/', params: params) }
its(:status) { should == 200 }
its(:content_type) { should == 'application/json' }
its(:body) { should include '"access_token":"access_token"' }
its(:body) { should include '"token_type":"bearer"' }
context 'when refresh_token is missing' do
before do
params.delete_if do |key, value|
key == :refresh_token
end
end
its(:status) { should == 400 }
its(:content_type) { should == 'application/json' }
its(:body) { should include '"error":"invalid_request"' }
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/authorize_spec.rb 0000644 0000041 0000041 00000015177 13410611536 023642 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Authorize do
let(:app) { Rack::OAuth2::Server::Authorize.new }
let(:request) { Rack::MockRequest.new app }
let(:redirect_uri) { 'http://client.example.com/callback' }
let(:bad_request) { Rack::OAuth2::Server::Authorize::BadRequest }
context 'when response_type is missing' do
it do
expect { request.get "/?client_id=client&redirect_uri=#{redirect_uri}" }.to raise_error bad_request
end
end
context 'when redirect_uri is missing' do
it do
expect { request.get "/?response_type=code&client_id=client" }.not_to raise_error
end
end
context 'when client_id is missing' do
it do
expect { request.get "/?response_type=code&redirect_uri=#{redirect_uri}" }.to raise_error bad_request
end
end
context 'when unknown response_type is given' do
it do
expect { request.get "/?response_type=unknown&client_id=client&redirect_uri=#{redirect_uri}" }.to raise_error bad_request
end
end
context 'when all required parameters are valid' do
[:code, :token].each do |request_type|
context "when response_type = :#{request_type}" do
subject { request.get "/?response_type=#{request_type}&client_id=client&redirect_uri=#{redirect_uri}" }
its(:status) { should == 200 }
end
end
end
describe Rack::OAuth2::Server::Authorize::Request do
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client&redirect_uri=#{redirect_uri}") }
let(:request) { Rack::OAuth2::Server::Authorize::Request.new env }
describe '#varified_redirect_uri' do
context 'when an Array of pre-registered URIs are given' do
context 'when given redirect_uri is valid against one of them' do
let :pre_registered do
[
redirect_uri,
'http://ja.client.example.com/callback',
'http://en.client.example.com/callback'
]
end
it 'should be valid' do
request.verify_redirect_uri!(pre_registered).should == redirect_uri
end
end
context 'otherwise' do
let :pre_registered do
[
'http://ja.client.example.com/callback',
'http://en.client.example.com/callback'
]
end
it do
expect do
request.verify_redirect_uri!(pre_registered)
end.to raise_error bad_request
end
end
end
context 'when exact mathed redirect_uri is given' do
let(:pre_registered) { redirect_uri }
it 'should be valid' do
request.verify_redirect_uri!(pre_registered).should == redirect_uri
end
end
context 'when partially mathed redirect_uri is given' do
let(:pre_registered) { 'http://client.example.com' }
context 'when partial matching allowed' do
it 'should be valid' do
request.verify_redirect_uri!(pre_registered, :allow_partial_match).should == redirect_uri
end
end
context 'otherwise' do
it do
expect do
request.verify_redirect_uri!(pre_registered)
end.to raise_error bad_request
end
end
end
context 'when invalid redirect_uri is given' do
let(:pre_registered) { 'http://client2.example.com' }
it do
expect do
request.verify_redirect_uri!(pre_registered)
end.to raise_error bad_request
end
end
context 'when redirect_uri is missing' do
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client") }
context 'when pre-registered redirect_uri is a String' do
let(:pre_registered) { redirect_uri }
it 'should use pre-registered redirect_uri' do
request.verify_redirect_uri!(pre_registered).should == pre_registered
end
end
context 'when pre-registered redirect_uri is an Array' do
context 'when only 1' do
let(:pre_registered) { [redirect_uri] }
context 'when partial match allowed' do
it do
expect do
request.verify_redirect_uri!(pre_registered, :allow_partial_match)
end.to raise_error bad_request
end
end
context 'otherwise' do
it 'should use pre-registered redirect_uri' do
request.verify_redirect_uri!(pre_registered).should == pre_registered.first
end
end
end
context 'when more than 2' do
let(:pre_registered) { [redirect_uri, 'http://client.example.com/callback2'] }
it do
expect do
request.verify_redirect_uri!(pre_registered)
end.to raise_error bad_request
end
end
end
end
end
end
describe 'extensibility' do
before do
require 'rack/oauth2/server/authorize/extension/code_and_token'
end
let(:env) do
Rack::MockRequest.env_for("/authorize?response_type=#{response_type}&client_id=client")
end
let(:request) { Rack::OAuth2::Server::Authorize::Request.new env }
its(:extensions) { should == [Rack::OAuth2::Server::Authorize::Extension::CodeAndToken] }
describe 'code token' do
let(:response_type) { 'code%20token' }
it do
app.send(
:response_type_for, request
).should == Rack::OAuth2::Server::Authorize::Extension::CodeAndToken
end
end
describe 'token code' do
let(:response_type) { 'token%20code' }
it do
app.send(
:response_type_for, request
).should == Rack::OAuth2::Server::Authorize::Extension::CodeAndToken
end
end
describe 'token code id_token' do
let(:response_type) { 'token%20code%20id_token' }
it do
expect do
app.send(:response_type_for, request)
end.to raise_error bad_request
end
end
describe 'id_token' do
before do
class Rack::OAuth2::Server::Authorize::Extension::IdToken < Rack::OAuth2::Server::Abstract::Handler
def self.response_type_for?(response_type)
response_type == 'id_token'
end
end
end
its(:extensions) do
should == [
Rack::OAuth2::Server::Authorize::Extension::CodeAndToken,
Rack::OAuth2::Server::Authorize::Extension::IdToken
]
end
let(:response_type) { 'id_token' }
it do
app.send(
:response_type_for, request
).should == Rack::OAuth2::Server::Authorize::Extension::IdToken
end
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/resource_spec.rb 0000644 0000041 0000041 00000001153 13410611536 023444 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Resource do
subject { Rack::OAuth2::Server::Resource.new(simple_app, 'realm') }
its(:realm) { should == 'realm' }
end
describe Rack::OAuth2::Server::Resource::Request do
let(:env) { Rack::MockRequest.env_for('/protected_resource') }
let(:request) { Rack::OAuth2::Server::Resource::Request.new(env) }
describe '#setup!' do
it do
expect { request.setup! }.to raise_error(RuntimeError, 'Define me!')
end
end
describe '#oauth2?' do
it do
expect { request.oauth2? }.to raise_error(RuntimeError, 'Define me!')
end
end
end rack-oauth2-1.9.3/spec/rack/oauth2/server/resource/ 0000755 0000041 0000041 00000000000 13410611536 022105 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/server/resource/mac/ 0000755 0000041 0000041 00000000000 13410611536 022645 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/server/resource/mac/error_spec.rb 0000644 0000041 0000041 00000003351 13410611536 025337 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Resource::MAC::Unauthorized do
let(:error) { Rack::OAuth2::Server::Resource::MAC::Unauthorized.new(:invalid_token) }
it { should be_a Rack::OAuth2::Server::Resource::Unauthorized }
describe '#scheme' do
subject { error }
its(:scheme) { should == :MAC }
end
describe '#finish' do
it 'should use MAC scheme' do
status, header, response = error.finish
header['WWW-Authenticate'].should =~ /^MAC /
end
end
end
describe Rack::OAuth2::Server::Resource::MAC::ErrorMethods do
let(:unauthorized) { Rack::OAuth2::Server::Resource::MAC::Unauthorized }
let(:redirect_uri) { 'http://client.example.com/callback' }
let(:default_description) { Rack::OAuth2::Server::Resource::ErrorMethods::DEFAULT_DESCRIPTION }
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client_id") }
let(:request) { Rack::OAuth2::Server::Resource::MAC::Request.new env }
describe 'unauthorized!' do
it do
expect { request.unauthorized! :invalid_client }.to raise_error unauthorized
end
end
Rack::OAuth2::Server::Resource::Bearer::ErrorMethods::DEFAULT_DESCRIPTION.keys.each do |error_code|
method = "#{error_code}!"
case error_code
when :invalid_request
# ignore
when :insufficient_scope
# ignore
else
describe method do
it "should raise Rack::OAuth2::Server::Resource::Bearer::Unauthorized with error = :#{error_code}" do
expect { request.send method }.to raise_error(unauthorized) { |error|
error.error.should == error_code
error.description.should == default_description[error_code]
}
end
end
end
end
end rack-oauth2-1.9.3/spec/rack/oauth2/server/resource/mac_spec.rb 0000644 0000041 0000041 00000010227 13410611536 024206 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Resource::MAC do
let(:app) do
Rack::OAuth2::Server::Resource::MAC.new(simple_app) do |request|
case request.access_token
when 'valid_token'
token = mac_token
token.verify!(request)
token
when 'insufficient_scope_token'
request.insufficient_scope!
else
request.invalid_token!
end
end
end
let(:mac_token) do
Rack::OAuth2::AccessToken::MAC.new(
access_token: 'valid_token',
mac_key: 'secret',
mac_algorithm: 'hmac-sha-256',
ts: 1305820230 # fix verification time
)
end
let(:access_token) { env[Rack::OAuth2::Server::Resource::ACCESS_TOKEN] }
let(:request) { app.call(env) }
subject { app.call(env) }
shared_examples_for :non_mac_request do
it 'should skip OAuth 2.0 authentication' do
status, header, response = request
status.should == 200
access_token.should be_nil
end
end
shared_examples_for :authenticated_mac_request do
it 'should be authenticated' do
status, header, response = request
status.should == 200
access_token.should == mac_token
end
end
shared_examples_for :unauthorized_mac_request do
it 'should be unauthorized' do
status, header, response = request
status.should == 401
header['WWW-Authenticate'].should include 'MAC'
access_token.should be_nil
end
end
shared_examples_for :bad_mac_request do
it 'should be unauthorized' do
status, header, response = request
status.should == 400
access_token.should be_nil
end
end
context 'when no access token is given' do
let(:env) { Rack::MockRequest.env_for('/protected_resource') }
it 'should skip OAuth 2.0 authentication' do
status, header, response = request
status.should == 200
access_token.should be_nil
end
end
context 'when valid_token is given' do
context 'when other required params are missing' do
let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'MAC id="valid_token"') }
it_behaves_like :unauthorized_mac_request
end
context 'when other required params are invalid' do
let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'MAC id="valid_token", nonce="51e74de734c05613f37520872e68db5f", ts="1305820234", mac="invalid""') }
it_behaves_like :unauthorized_mac_request
end
context 'when all required params are valid' do
let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'MAC id="valid_token", nonce="51e74de734c05613f37520872e68db5f", ts="1305820234", mac="26JP6MMZyAHLHeMU8+m+NbVJgZbikp5SlT86/a62pwg="') }
it_behaves_like :authenticated_mac_request
end
context 'when all required params are valid and ts is expired' do
let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'MAC id="valid_token", nonce="51e74de734c05613f37520872e68db5f", ts="1305819234", mac="nuo4765MZrVL/qMsAtuTczhqZAE5y02ChaLCyOiVU68="') }
it_behaves_like :unauthorized_mac_request
end
end
context 'when invalid_token is given' do
let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'MAC id="invalid_token"') }
it_behaves_like :unauthorized_mac_request
describe 'realm' do
let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'MAC id="invalid_token"') }
context 'when specified' do
let(:realm) { 'server.example.com' }
let(:app) do
Rack::OAuth2::Server::Resource::MAC.new(simple_app, realm) do |request|
request.unauthorized!
end
end
it 'should use specified realm' do
status, header, response = request
header['WWW-Authenticate'].should include "MAC realm=\"#{realm}\""
end
end
context 'otherwize' do
it 'should use default realm' do
status, header, response = request
header['WWW-Authenticate'].should include "MAC realm=\"#{Rack::OAuth2::Server::Resource::DEFAULT_REALM}\""
end
end
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/resource/error_spec.rb 0000644 0000041 0000041 00000012733 13410611536 024603 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Resource::BadRequest do
let(:error) { Rack::OAuth2::Server::Resource::BadRequest.new(:invalid_request) }
it { should be_a Rack::OAuth2::Server::Abstract::BadRequest }
describe '#finish' do
it 'should respond in JSON' do
status, header, response = error.finish
status.should == 400
header['Content-Type'].should == 'application/json'
response.body.should == ['{"error":"invalid_request"}']
end
end
end
describe Rack::OAuth2::Server::Resource::Unauthorized do
let(:error) { Rack::OAuth2::Server::Resource::Unauthorized.new(:invalid_token) }
let(:realm) { Rack::OAuth2::Server::Resource::DEFAULT_REALM }
it { should be_a Rack::OAuth2::Server::Abstract::Unauthorized }
describe '#scheme' do
it do
expect { error.scheme }.to raise_error(RuntimeError, 'Define me!')
end
end
context 'when scheme is defined' do
let :error_with_scheme do
e = error
e.instance_eval do
def scheme
:Scheme
end
end
e
end
describe '#finish' do
it 'should respond in JSON' do
status, header, response = error_with_scheme.finish
status.should == 401
header['Content-Type'].should == 'application/json'
header['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\", error=\"invalid_token\""
response.body.should == ['{"error":"invalid_token"}']
end
context 'when error_code is not invalid_token' do
let(:error) { Rack::OAuth2::Server::Resource::Unauthorized.new(:something) }
it 'should have error_code in body but not in WWW-Authenticate header' do
status, header, response = error_with_scheme.finish
header['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\""
response.body.first.should include '"error":"something"'
end
end
context 'when no error_code is given' do
let(:error) { Rack::OAuth2::Server::Resource::Unauthorized.new }
it 'should have error_code in body but not in WWW-Authenticate header' do
status, header, response = error_with_scheme.finish
header['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\""
response.body.first.should == '{"error":"unauthorized"}'
end
end
context 'when realm is specified' do
let(:realm) { 'server.example.com' }
let(:error) { Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new(:something, nil, realm: realm) }
it 'should use given realm' do
status, header, response = error_with_scheme.finish
header['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\""
response.body.first.should include '"error":"something"'
end
end
end
end
end
describe Rack::OAuth2::Server::Resource::Forbidden do
let(:error) { Rack::OAuth2::Server::Resource::Forbidden.new(:insufficient_scope) }
it { should be_a Rack::OAuth2::Server::Abstract::Forbidden }
describe '#finish' do
it 'should respond in JSON' do
status, header, response = error.finish
status.should == 403
header['Content-Type'].should == 'application/json'
response.body.should == ['{"error":"insufficient_scope"}']
end
end
context 'when scope option is given' do
let(:error) { Rack::OAuth2::Server::Resource::Bearer::Forbidden.new(:insufficient_scope, 'Desc', scope: [:scope1, :scope2]) }
it 'should have blank WWW-Authenticate header' do
status, header, response = error.finish
response.body.first.should include '"scope":"scope1 scope2"'
end
end
end
describe Rack::OAuth2::Server::Resource::Bearer::ErrorMethods do
let(:bad_request) { Rack::OAuth2::Server::Resource::BadRequest }
let(:forbidden) { Rack::OAuth2::Server::Resource::Forbidden }
let(:redirect_uri) { 'http://client.example.com/callback' }
let(:default_description) { Rack::OAuth2::Server::Resource::ErrorMethods::DEFAULT_DESCRIPTION }
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client_id") }
let(:request) { Rack::OAuth2::Server::Resource::Request.new env }
describe 'bad_request!' do
it do
expect { request.bad_request! :invalid_request }.to raise_error bad_request
end
end
describe 'unauthorized!' do
it do
expect { request.unauthorized! :invalid_client }.to raise_error(RuntimeError, 'Define me!')
end
end
Rack::OAuth2::Server::Resource::ErrorMethods::DEFAULT_DESCRIPTION.keys.each do |error_code|
method = "#{error_code}!"
case error_code
when :invalid_request
describe method do
it "should raise Rack::OAuth2::Server::Resource::BadRequest with error = :#{error_code}" do
expect { request.send method }.to raise_error(bad_request) { |error|
error.error.should == error_code
error.description.should == default_description[error_code]
}
end
end
when :insufficient_scope
describe method do
it "should raise Rack::OAuth2::Server::Resource::Forbidden with error = :#{error_code}" do
expect { request.send method }.to raise_error(forbidden) { |error|
error.error.should == error_code
error.description.should == default_description[error_code]
}
end
end
else
describe method do
it do
expect { request.send method }.to raise_error(RuntimeError, 'Define me!')
end
end
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/resource/bearer/ 0000755 0000041 0000041 00000000000 13410611536 023345 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/server/resource/bearer/error_spec.rb 0000644 0000041 0000041 00000003404 13410611536 026036 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Resource::Bearer::Unauthorized do
let(:error) { Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new(:invalid_token) }
it { should be_a Rack::OAuth2::Server::Resource::Unauthorized }
describe '#scheme' do
subject { error }
its(:scheme) { should == :Bearer }
end
describe '#finish' do
it 'should use Bearer scheme' do
status, header, response = error.finish
header['WWW-Authenticate'].should include 'Bearer'
end
end
end
describe Rack::OAuth2::Server::Resource::Bearer::ErrorMethods do
let(:unauthorized) { Rack::OAuth2::Server::Resource::Bearer::Unauthorized }
let(:redirect_uri) { 'http://client.example.com/callback' }
let(:default_description) { Rack::OAuth2::Server::Resource::ErrorMethods::DEFAULT_DESCRIPTION }
let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client_id") }
let(:request) { Rack::OAuth2::Server::Resource::Bearer::Request.new env }
describe 'unauthorized!' do
it do
expect { request.unauthorized! :invalid_client }.to raise_error unauthorized
end
end
Rack::OAuth2::Server::Resource::Bearer::ErrorMethods::DEFAULT_DESCRIPTION.keys.each do |error_code|
method = "#{error_code}!"
case error_code
when :invalid_request
# ignore
when :insufficient_scope
# ignore
else
describe method do
it "should raise Rack::OAuth2::Server::Resource::Bearer::Unauthorized with error = :#{error_code}" do
expect { request.send method }.to raise_error(unauthorized) { |error|
error.error.should == error_code
error.description.should == default_description[error_code]
}
end
end
end
end
end rack-oauth2-1.9.3/spec/rack/oauth2/server/resource/bearer_spec.rb 0000644 0000041 0000041 00000007636 13410611536 024720 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Resource::Bearer do
let(:app) do
Rack::OAuth2::Server::Resource::Bearer.new(simple_app) do |request|
case request.access_token
when 'valid_token'
bearer_token
when 'insufficient_scope_token'
request.insufficient_scope!
else
request.invalid_token!
end
end
end
let(:bearer_token) do
Rack::OAuth2::AccessToken::Bearer.new(access_token: 'valid_token')
end
let(:access_token) { env[Rack::OAuth2::Server::Resource::ACCESS_TOKEN] }
let(:request) { app.call(env) }
subject { app.call(env) }
shared_examples_for :authenticated_bearer_request do
it 'should be authenticated' do
status, header, response = request
status.should == 200
access_token.should == bearer_token
end
end
shared_examples_for :unauthorized_bearer_request do
it 'should be unauthorized' do
status, header, response = request
status.should == 401
header['WWW-Authenticate'].should include 'Bearer'
access_token.should be_nil
end
end
shared_examples_for :bad_bearer_request do
it 'should be bad_request' do
status, header, response = request
status.should == 400
access_token.should be_nil
end
end
shared_examples_for :skipped_authentication_request do
it 'should skip OAuth 2.0 authentication' do
status, header, response = request
status.should == 200
access_token.should be_nil
end
end
context 'when no access token is given' do
let(:env) { Rack::MockRequest.env_for('/protected_resource') }
it_behaves_like :skipped_authentication_request
end
context 'when valid_token is given' do
context 'when token is in Authorization header' do
let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'Bearer valid_token') }
it_behaves_like :authenticated_bearer_request
end
context 'when token is in params' do
let(:env) { Rack::MockRequest.env_for('/protected_resource', params: {access_token: 'valid_token'}) }
it_behaves_like :authenticated_bearer_request
end
end
context 'when invalid authorization header is given' do
let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => '') }
it_behaves_like :skipped_authentication_request
end
context 'when invalid_token is given' do
let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'Bearer invalid_token') }
context 'when token is in Authorization header' do
it_behaves_like :unauthorized_bearer_request
end
context 'when token is in params' do
let(:env) { Rack::MockRequest.env_for('/protected_resource', params: {access_token: 'invalid_token'}) }
it_behaves_like :unauthorized_bearer_request
end
describe 'realm' do
context 'when specified' do
let(:realm) { 'server.example.com' }
let(:app) do
Rack::OAuth2::Server::Resource::Bearer.new(simple_app, realm) do |request|
request.unauthorized!
end
end
it 'should use specified realm' do
status, header, response = request
header['WWW-Authenticate'].should include "Bearer realm=\"#{realm}\""
end
end
context 'otherwize' do
it 'should use default realm' do
status, header, response = request
header['WWW-Authenticate'].should include "Bearer realm=\"#{Rack::OAuth2::Server::Resource::Bearer::DEFAULT_REALM}\""
end
end
end
end
context 'when multiple access_token is given' do
context 'when token is in Authorization header and params' do
let(:env) do
Rack::MockRequest.env_for(
'/protected_resource',
'HTTP_AUTHORIZATION' => 'Bearer valid_token',
params: {access_token: 'valid_token'}
)
end
it_behaves_like :bad_bearer_request
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/extension/ 0000755 0000041 0000041 00000000000 13410611536 022272 5 ustar www-data www-data rack-oauth2-1.9.3/spec/rack/oauth2/server/extension/pkce_spec.rb 0000644 0000041 0000041 00000012206 13410611536 024554 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Authorize::Code do
let(:request) { Rack::MockRequest.new app }
let(:redirect_uri) { 'http://client.example.com/callback' }
let(:code_verifier) { SecureRandom.hex(16) }
let(:code_challenge) { Base64.urlsafe_encode64(OpenSSL::Digest::SHA256.digest(code_verifier)).delete('=') }
let(:code_challenge_method) { :S256 }
subject { @request }
describe 'authorization request' do
let :app do
Rack::OAuth2::Server::Authorize.new do |request, response|
@request = request
end
end
context 'when code_challenge is given' do
context 'when code_challenge_method is given' do
before do
request.get "/?response_type=code&client_id=client&redirect_uri=#{redirect_uri}&state=state&code_challenge=#{code_challenge}&code_challenge_method=#{code_challenge_method}"
end
its(:code_challenge) { should == code_challenge }
its(:code_challenge_method) { should == code_challenge_method.to_s }
end
context 'when code_challenge_method is omitted' do
before do
request.get "/?response_type=code&client_id=client&redirect_uri=#{redirect_uri}&state=state&code_challenge=#{code_challenge}"
end
its(:code_challenge) { should == code_challenge }
its(:code_challenge_method) { should == nil }
end
end
context 'otherwise' do
before do
request.get "/?response_type=code&client_id=client&redirect_uri=#{redirect_uri}&state=state"
end
its(:code_challenge) { should == nil }
its(:code_challenge_method) { should == nil }
end
end
describe 'token request' do
let(:app) do
Rack::OAuth2::Server::Token.new do |request, response|
@request = request
response.access_token = Rack::OAuth2::AccessToken::Bearer.new(access_token: 'access_token')
end
end
let(:default_params) do
{
grant_type: 'authorization_code',
client_id: 'client_id',
client_secret: 'client_secret',
code: 'authorization_code',
redirect_uri: 'http://client.example.com/callback'
}
end
context 'when code_verifier is given' do
before do
request.post '/', params: default_params.merge(
code_verifier: code_verifier
)
end
its(:code_verifier) { should == code_verifier }
describe '#verify_code_verifier!' do
context 'when code_verifier is given with code_challenge_method=plain' do
it do
expect do
subject.verify_code_verifier! code_verifier, :plain
end.not_to raise_error
end
end
context 'when collect code_challenge is given' do
it do
expect do
subject.verify_code_verifier! code_challenge
end.not_to raise_error
end
end
context 'when wrong code_challenge is blank' do
it do
expect do
subject.verify_code_verifier! 'wrong'
end.to raise_error Rack::OAuth2::Server::Token::BadRequest, /invalid_grant/
end
end
context 'when code_challenge is nil' do
it do
expect do
subject.verify_code_verifier! nil
end.to raise_error Rack::OAuth2::Server::Token::BadRequest, /invalid_grant/
end
end
context 'when unknown code_challenge_method is given' do
it do
expect do
subject.verify_code_verifier! code_challenge, :unknown
end.to raise_error Rack::OAuth2::Server::Token::BadRequest, /invalid_grant/
end
end
end
end
context 'otherwise' do
before do
request.post '/', params: default_params
end
its(:code_verifier) { should == nil }
describe '#verify_code_verifier!' do
context 'when code_verifier is given with code_challenge_method=plain' do
it do
expect do
subject.verify_code_verifier! code_verifier, :plain
end.to raise_error Rack::OAuth2::Server::Token::BadRequest, /invalid_grant/
end
end
context 'when collect code_challenge is given' do
it do
expect do
subject.verify_code_verifier! code_challenge
end.to raise_error Rack::OAuth2::Server::Token::BadRequest, /invalid_grant/
end
end
context 'when wrong code_challenge is blank' do
it do
expect do
subject.verify_code_verifier! 'wrong'
end.to raise_error Rack::OAuth2::Server::Token::BadRequest, /invalid_grant/
end
end
context 'when code_challenge is nil' do
it do
expect do
subject.verify_code_verifier! nil
end.not_to raise_error
end
end
context 'when unknown code_challenge_method is given' do
it do
expect do
subject.verify_code_verifier! code_challenge, :unknown
end.to raise_error Rack::OAuth2::Server::Token::BadRequest, /invalid_grant/
end
end
end
end
end
end
rack-oauth2-1.9.3/spec/rack/oauth2/server/extension/response_mode_spec.rb 0000644 0000041 0000041 00000001600 13410611536 026470 0 ustar www-data www-data require 'spec_helper.rb'
describe Rack::OAuth2::Server::Authorize::Code do
let(:request) { Rack::MockRequest.new app }
let(:redirect_uri) { 'http://client.example.com/callback' }
let(:response_mode) { 'form_post' }
subject { @request }
describe 'authorization request' do
let :app do
Rack::OAuth2::Server::Authorize.new do |request, response|
@request = request
end
end
context 'when response_mode is given' do
before do
request.get "/?response_type=code&client_id=client&redirect_uri=#{redirect_uri}&state=state&response_mode=#{response_mode}"
end
its(:response_mode) { should == response_mode }
end
context 'otherwise' do
before do
request.get "/?response_type=code&client_id=client&redirect_uri=#{redirect_uri}&state=state"
end
its(:response_mode) { should == nil }
end
end
end
rack-oauth2-1.9.3/spec/mock_response/ 0000755 0000041 0000041 00000000000 13410611536 017475 5 ustar www-data www-data rack-oauth2-1.9.3/spec/mock_response/errors/ 0000755 0000041 0000041 00000000000 13410611536 021011 5 ustar www-data www-data rack-oauth2-1.9.3/spec/mock_response/errors/invalid_request.json 0000644 0000041 0000041 00000000112 13410611536 025074 0 ustar www-data www-data {
"error":"invalid_request",
"error_description":"error description"
} rack-oauth2-1.9.3/spec/mock_response/resources/ 0000755 0000041 0000041 00000000000 13410611536 021507 5 ustar www-data www-data rack-oauth2-1.9.3/spec/mock_response/resources/fake.txt 0000644 0000041 0000041 00000000004 13410611536 023150 0 ustar www-data www-data fake rack-oauth2-1.9.3/spec/mock_response/blank 0000644 0000041 0000041 00000000000 13410611536 020475 0 ustar www-data www-data rack-oauth2-1.9.3/spec/mock_response/tokens/ 0000755 0000041 0000041 00000000000 13410611536 021000 5 ustar www-data www-data rack-oauth2-1.9.3/spec/mock_response/tokens/legacy_without_expires_in.txt 0000644 0000041 0000041 00000000031 13410611536 027007 0 ustar www-data www-data access_token=access_token rack-oauth2-1.9.3/spec/mock_response/tokens/unknown.json 0000644 0000041 0000041 00000000165 13410611536 023374 0 ustar www-data www-data {
"access_token":"access_token",
"refresh_token":"refresh_token",
"token_type":"unknown",
"expires_in":3600
} rack-oauth2-1.9.3/spec/mock_response/tokens/legacy.txt 0000644 0000041 0000041 00000000046 13410611536 023005 0 ustar www-data www-data access_token=access_token&expires=3600 rack-oauth2-1.9.3/spec/mock_response/tokens/_Bearer.json 0000644 0000041 0000041 00000000164 13410611536 023233 0 ustar www-data www-data {
"access_token":"access_token",
"refresh_token":"refresh_token",
"token_type":"Bearer",
"expires_in":3600
} rack-oauth2-1.9.3/spec/mock_response/tokens/legacy.json 0000644 0000041 0000041 00000000133 13410611536 023134 0 ustar www-data www-data {
"access_token":"access_token",
"refresh_token":"refresh_token",
"expires_in":3600
} rack-oauth2-1.9.3/spec/mock_response/tokens/mac.json 0000644 0000041 0000041 00000000252 13410611536 022432 0 ustar www-data www-data {
"token_type":"mac",
"mac_algorithm":"hmac-sha-256",
"expires_in":3600,
"mac_key":"secret",
"refresh_token":"refresh_token",
"access_token":"access_token"
}
rack-oauth2-1.9.3/spec/mock_response/tokens/bearer.json 0000644 0000041 0000041 00000000164 13410611536 023134 0 ustar www-data www-data {
"access_token":"access_token",
"refresh_token":"refresh_token",
"token_type":"bearer",
"expires_in":3600
} rack-oauth2-1.9.3/spec/spec_helper.rb 0000644 0000041 0000041 00000000605 13410611536 017445 0 ustar www-data www-data require 'simplecov'
SimpleCov.start do
add_filter 'spec'
end
require 'rspec'
require 'rspec/its'
require 'rack/oauth2'
RSpec.configure do |config|
config.expect_with :rspec do |c|
c.syntax = [:should, :expect]
end
end
require 'helpers/time'
require 'helpers/webmock_helper'
def simple_app
lambda do |env|
[ 200, {'Content-Type' => 'text/plain'}, ["HELLO"] ]
end
end
rack-oauth2-1.9.3/.gitignore 0000644 0000041 0000041 00000000240 13410611536 015660 0 ustar www-data www-data ## MAC OS
.DS_Store
## TEXTMATE
*.tmproj
tmtags
## EMACS
*~
\#*
.\#*
## VIM
*.swp
## PROJECT::GENERAL
coverage*
rdoc
pkg
Gemfile.lock
## PROJECT::SPECIFIC
rack-oauth2-1.9.3/LICENSE 0000644 0000041 0000041 00000002036 13410611536 014702 0 ustar www-data www-data Copyright (c) 2010 nov matake
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
rack-oauth2-1.9.3/.document 0000644 0000041 0000041 00000000074 13410611536 015514 0 ustar www-data www-data README.rdoc
lib/**/*.rb
bin/*
features/**/*.feature
LICENSE
rack-oauth2-1.9.3/Rakefile 0000644 0000041 0000041 00000000620 13410611536 015337 0 ustar www-data www-data require 'bundler'
Bundler::GemHelper.install_tasks
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec)
namespace :coverage do
desc "Open coverage report"
task :report do
require 'simplecov'
`open "#{File.join SimpleCov.coverage_path, 'index.html'}"`
end
end
task :spec do
Rake::Task[:'coverage:report'].invoke unless ENV['TRAVIS_RUBY_VERSION']
end
task default: :spec
rack-oauth2-1.9.3/lib/ 0000755 0000041 0000041 00000000000 13410611536 014442 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/ 0000755 0000041 0000041 00000000000 13410611536 015362 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2.rb 0000644 0000041 0000041 00000003022 13410611536 017106 0 ustar www-data www-data require 'rack'
require 'httpclient'
require 'logger'
require 'active_support'
require 'active_support/core_ext'
require 'attr_required'
require 'attr_optional'
module Rack
module OAuth2
VERSION = ::File.read(
::File.join(::File.dirname(__FILE__), '../../VERSION')
).strip
def self.logger
@@logger
end
def self.logger=(logger)
@@logger = logger
end
self.logger = ::Logger.new(STDOUT)
self.logger.progname = 'Rack::OAuth2'
def self.debugging?
@@debugging
end
def self.debugging=(boolean)
@@debugging = boolean
end
def self.debug!
self.debugging = true
end
def self.debug(&block)
original = self.debugging?
self.debugging = true
yield
ensure
self.debugging = original
end
self.debugging = false
def self.http_client(agent_name = "Rack::OAuth2 (#{VERSION})", &local_http_config)
_http_client_ = HTTPClient.new(
agent_name: agent_name
)
http_config.try(:call, _http_client_)
local_http_config.try(:call, _http_client_) unless local_http_config.nil?
_http_client_.request_filter << Debugger::RequestFilter.new if debugging?
_http_client_
end
def self.http_config(&block)
@@http_config ||= block
end
def self.reset_http_config!
@@http_config = nil
end
end
end
require 'rack/oauth2/urn'
require 'rack/oauth2/util'
require 'rack/oauth2/server'
require 'rack/oauth2/client'
require 'rack/oauth2/access_token'
require 'rack/oauth2/debugger'
rack-oauth2-1.9.3/lib/rack/oauth2/ 0000755 0000041 0000041 00000000000 13410611536 016564 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/client/ 0000755 0000041 0000041 00000000000 13410611536 020042 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/client/grant.rb 0000644 0000041 0000041 00000001763 13410611536 021511 0 ustar www-data www-data module Rack
module OAuth2
class Client
class Grant
include AttrRequired, AttrOptional
def initialize(attributes = {})
(required_attributes + optional_attributes).each do |key|
self.send "#{key}=", attributes[key]
end
attr_missing!
end
def grant_type
self.class.name.demodulize.underscore.to_sym
end
def as_json(options = {})
(required_attributes + optional_attributes).inject({
grant_type: grant_type
}) do |hash, key|
hash.merge! key => self.send(key)
end
end
end
end
end
end
require 'rack/oauth2/client/grant/authorization_code'
require 'rack/oauth2/client/grant/password'
require 'rack/oauth2/client/grant/client_credentials'
require 'rack/oauth2/client/grant/refresh_token'
require 'rack/oauth2/client/grant/jwt_bearer'
require 'rack/oauth2/client/grant/saml2_bearer'
require 'rack/oauth2/client/grant/token_exchange' rack-oauth2-1.9.3/lib/rack/oauth2/client/grant/ 0000755 0000041 0000041 00000000000 13410611536 021155 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/client/grant/authorization_code.rb 0000644 0000041 0000041 00000000322 13410611536 025371 0 ustar www-data www-data module Rack
module OAuth2
class Client
class Grant
class AuthorizationCode < Grant
attr_required :code
attr_optional :redirect_uri
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/client/grant/saml2_bearer.rb 0000644 0000041 0000041 00000000374 13410611536 024044 0 ustar www-data www-data module Rack
module OAuth2
class Client
class Grant
class SAML2Bearer < Grant
attr_required :assertion
def grant_type
URN::GrantType::SAML2_BEARER
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/client/grant/refresh_token.rb 0000644 0000041 0000041 00000000260 13410611536 024336 0 ustar www-data www-data module Rack
module OAuth2
class Client
class Grant
class RefreshToken < Grant
attr_required :refresh_token
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/client/grant/jwt_bearer.rb 0000644 0000041 0000041 00000000370 13410611536 023626 0 ustar www-data www-data module Rack
module OAuth2
class Client
class Grant
class JWTBearer < Grant
attr_required :assertion
def grant_type
URN::GrantType::JWT_BEARER
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/client/grant/client_credentials.rb 0000644 0000041 0000041 00000000216 13410611536 025334 0 ustar www-data www-data module Rack
module OAuth2
class Client
class Grant
class ClientCredentials < Grant
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/client/grant/token_exchange.rb 0000644 0000041 0000041 00000000431 13410611536 024462 0 ustar www-data www-data module Rack
module OAuth2
class Client
class Grant
class TokenExchange < Grant
attr_required :subject_token, :subject_token_type
def grant_type
URN::GrantType::TOKEN_EXCHANGE
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/client/grant/password.rb 0000644 0000041 0000041 00000000262 13410611536 023344 0 ustar www-data www-data module Rack
module OAuth2
class Client
class Grant
class Password < Grant
attr_required :username, :password
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/client/error.rb 0000644 0000041 0000041 00000000565 13410611536 021526 0 ustar www-data www-data module Rack
module OAuth2
class Client
class Error < StandardError
attr_accessor :status, :response
def initialize(status, response)
@status = status
@response = response
message = [response[:error], response[:error_description]].compact.join(' :: ')
super message
end
end
end
end
end
rack-oauth2-1.9.3/lib/rack/oauth2/debugger/ 0000755 0000041 0000041 00000000000 13410611536 020350 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/debugger/request_filter.rb 0000644 0000041 0000041 00000001471 13410611536 023735 0 ustar www-data www-data module Rack
module OAuth2
module Debugger
class RequestFilter
# Callback called in HTTPClient (before sending a request)
# request:: HTTP::Message
def filter_request(request)
started = "======= [Rack::OAuth2] HTTP REQUEST STARTED ======="
log started, request.dump
end
# Callback called in HTTPClient (after received a response)
# request:: HTTP::Message
# response:: HTTP::Message
def filter_response(request, response)
finished = "======= [Rack::OAuth2] HTTP REQUEST FINISHED ======="
log '-' * 50, response.dump, finished
end
private
def log(*outputs)
outputs.each do |output|
OAuth2.logger.info output
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/debugger.rb 0000644 0000041 0000041 00000000120 13410611536 020666 0 ustar www-data www-data Dir[File.dirname(__FILE__) + '/debugger/*.rb'].each do |file|
require file
end rack-oauth2-1.9.3/lib/rack/oauth2/client.rb 0000644 0000041 0000041 00000013046 13410611536 020373 0 ustar www-data www-data module Rack
module OAuth2
class Client
include AttrRequired, AttrOptional
attr_required :identifier
attr_optional :secret, :private_key, :certificate, :redirect_uri, :scheme, :host, :port, :authorization_endpoint, :token_endpoint
def initialize(attributes = {})
(required_attributes + optional_attributes).each do |key|
self.send :"#{key}=", attributes[key]
end
@grant = Grant::ClientCredentials.new
@authorization_endpoint ||= '/oauth2/authorize'
@token_endpoint ||= '/oauth2/token'
attr_missing!
end
def authorization_uri(params = {})
params[:response_type] ||= :code
params[:response_type] = Array(params[:response_type]).join(' ')
params[:scope] = Array(params[:scope]).join(' ')
Util.redirect_uri absolute_uri_for(authorization_endpoint), :query, params.merge(
client_id: self.identifier,
redirect_uri: self.redirect_uri
)
end
def authorization_code=(code)
@grant = Grant::AuthorizationCode.new(
code: code,
redirect_uri: self.redirect_uri
)
end
def resource_owner_credentials=(credentials)
@grant = Grant::Password.new(
username: credentials.first,
password: credentials.last
)
end
def refresh_token=(token)
@grant = Grant::RefreshToken.new(
refresh_token: token
)
end
def jwt_bearer=(assertion)
@grant = Grant::JWTBearer.new(
assertion: assertion
)
end
def saml2_bearer=(assertion)
@grant = Grant::SAML2Bearer.new(
assertion: assertion
)
end
def subject_token=(subject_token, subject_token_type = URN::TokenType::JWT)
@grant = Grant::TokenExchange.new(
subject_token: subject_token,
subject_token_type: subject_token_type
)
end
def force_token_type!(token_type)
@forced_token_type = token_type.to_s
end
def access_token!(*args)
headers, params = {}, @grant.as_json
http_client = Rack::OAuth2.http_client
# NOTE:
# Using Array#estract_options! for backward compatibility.
# Until v1.0.5, the first argument was 'client_auth_method' in scalar.
options = args.extract_options!
client_auth_method = args.first || options.delete(:client_auth_method) || :basic
params[:scope] = Array(options.delete(:scope)).join(' ') if options[:scope].present?
params.merge! options
case client_auth_method
when :basic
cred = ["#{identifier}:#{secret}"].pack('m').tr("\n", '')
headers.merge!(
'Authorization' => "Basic #{cred}"
)
when :jwt_bearer
params.merge!(
client_assertion_type: URN::ClientAssertionType::JWT_BEARER
)
# NOTE: optionally auto-generate client_assertion.
if params[:client_assertion].blank?
require 'json/jwt'
params[:client_assertion] = JSON::JWT.new(
iss: identifier,
sub: identifier,
aud: absolute_uri_for(token_endpoint),
jti: SecureRandom.hex(16),
iat: Time.now,
exp: 3.minutes.from_now
).sign(private_key || secret).to_s
end
when :saml2_bearer
params.merge!(
client_assertion_type: URN::ClientAssertionType::SAML2_BEARER
)
when :mtls
params.merge!(
client_id: identifier
)
http_client.ssl_config.client_key = private_key
http_client.ssl_config.client_cert = certificate
else
params.merge!(
client_id: identifier,
client_secret: secret
)
end
handle_response do
http_client.post(
absolute_uri_for(token_endpoint),
Util.compact_hash(params),
headers
)
end
end
private
def absolute_uri_for(endpoint)
_endpoint_ = Util.parse_uri endpoint
_endpoint_.scheme ||= self.scheme || 'https'
_endpoint_.host ||= self.host
_endpoint_.port ||= self.port
raise 'No Host Info' unless _endpoint_.host
_endpoint_.to_s
end
def handle_response
response = yield
case response.status
when 200..201
handle_success_response response
else
handle_error_response response
end
end
def handle_success_response(response)
token_hash = JSON.parse(response.body).with_indifferent_access
case (@forced_token_type || token_hash[:token_type]).try(:downcase)
when 'bearer'
AccessToken::Bearer.new(token_hash)
when 'mac'
AccessToken::MAC.new(token_hash)
when nil
AccessToken::Legacy.new(token_hash)
else
raise 'Unknown Token Type'
end
rescue JSON::ParserError
# NOTE: Facebook support (They don't use JSON as token response)
AccessToken::Legacy.new Rack::Utils.parse_nested_query(response.body).with_indifferent_access
end
def handle_error_response(response)
error = JSON.parse(response.body).with_indifferent_access
raise Error.new(response.status, error)
rescue JSON::ParserError
raise Error.new(response.status, error: 'Unknown', error_description: response.body)
end
end
end
end
require 'rack/oauth2/client/error'
require 'rack/oauth2/client/grant'
rack-oauth2-1.9.3/lib/rack/oauth2/urn.rb 0000644 0000041 0000041 00000001643 13410611536 017721 0 ustar www-data www-data module Rack
module OAuth2
module URN
module TokenType
JWT = 'urn:ietf:params:oauth:token-type:jwt' # RFC7519
ACCESS_TOKEN = 'urn:ietf:params:oauth:token-type:access-token' # draft-ietf-oauth-token-exchange
REFRESH_TOKEN = 'urn:ietf:params:oauth:token-type:refresh-token' # draft-ietf-oauth-token-exchange
end
module GrantType
JWT_BEARER = 'urn:ietf:params:oauth:grant-type:jwt-bearer' # RFC7523
SAML2_BEARER = 'urn:ietf:params:oauth:grant-type:saml2-bearer' # RFC7522
TOKEN_EXCHANGE = 'urn:ietf:params:oauth:grant-type:token-exchange' # draft-ietf-oauth-token-exchange
end
module ClientAssertionType
JWT_BEARER = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer' # RFC7523
SAML2_BEARER = 'urn:ietf:params:oauth:client-assertion-type:saml2-bearer' # RFC7522
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/access_token/ 0000755 0000041 0000041 00000000000 13410611536 021225 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/access_token/mac/ 0000755 0000041 0000041 00000000000 13410611536 021765 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/access_token/mac/verifier.rb 0000644 0000041 0000041 00000002231 13410611536 024123 0 ustar www-data www-data module Rack
module OAuth2
class AccessToken
class MAC
class Verifier
include AttrRequired, AttrOptional
attr_required :algorithm
class VerificationFailed < StandardError; end
def initialize(attributes = {})
(required_attributes + optional_attributes).each do |key|
self.send :"#{key}=", attributes[key]
end
attr_missing!
rescue AttrRequired::AttrMissing => e
raise VerificationFailed.new("#{self.class.name.demodulize} Invalid: #{e.message}")
end
def verify!(expected)
if expected == self.calculate
:verified
else
raise VerificationFailed.new("#{self.class.name.demodulize} Invalid")
end
end
private
def hash_generator
case algorithm.to_s
when 'hmac-sha-1'
OpenSSL::Digest::SHA1.new
when 'hmac-sha-256'
OpenSSL::Digest::SHA256.new
else
raise 'Unsupported Algorithm'
end
end
end
end
end
end
end
rack-oauth2-1.9.3/lib/rack/oauth2/access_token/mac/signature.rb 0000644 0000041 0000041 00000001363 13410611536 024316 0 ustar www-data www-data module Rack
module OAuth2
class AccessToken
class MAC
class Signature < Verifier
attr_required :secret, :ts, :nonce, :method, :request_uri, :host, :port
attr_optional :ext, :query
def calculate
Rack::OAuth2::Util.base64_encode OpenSSL::HMAC.digest(
hash_generator,
secret,
normalized_request_string
)
end
def normalized_request_string
[
ts.to_i,
nonce,
method.to_s.upcase,
request_uri,
host,
port,
ext || '',
nil
].join("\n")
end
end
end
end
end
end
rack-oauth2-1.9.3/lib/rack/oauth2/access_token/mac/sha256_hex_verifier.rb 0000644 0000041 0000041 00000000546 13410611536 026066 0 ustar www-data www-data module Rack
module OAuth2
class AccessToken
class MAC
class Sha256HexVerifier < Verifier
attr_optional :raw_body
def calculate
return nil unless raw_body.present?
OpenSSL::Digest::SHA256.new.digest(raw_body).unpack('H*').first
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/access_token/mac.rb 0000644 0000041 0000041 00000006113 13410611536 022313 0 ustar www-data www-data module Rack
module OAuth2
class AccessToken
class MAC < AccessToken
attr_required :mac_key, :mac_algorithm
attr_optional :ts, :ext_verifier, :ts_expires_in
attr_reader :nonce, :signature, :ext
def initialize(attributes = {})
super(attributes)
@issued_at = Time.now.utc
@ts_expires_in ||= 5.minutes
end
def token_response
super.merge(
mac_key: mac_key,
mac_algorithm: mac_algorithm
)
end
def verify!(request)
if self.ext_verifier.present?
body = request.body.read
request.body.rewind # for future use
self.ext_verifier.new(
raw_body: body,
algorithm: self.mac_algorithm
).verify!(request.ext)
end
now = Time.now.utc.to_i
now = @ts.to_i if @ts.present?
raise Rack::OAuth2::AccessToken::MAC::Verifier::VerificationFailed.new("Request ts expired") if now - request.ts.to_i > @ts_expires_in.to_i
Signature.new(
secret: self.mac_key,
algorithm: self.mac_algorithm,
nonce: request.nonce,
method: request.request_method,
request_uri: request.fullpath,
host: request.host,
port: request.port,
ts: request.ts,
ext: request.ext
).verify!(request.signature)
rescue Verifier::VerificationFailed => e
request.invalid_token! e.message
end
def authenticate(request)
@nonce = generate_nonce
@ts_generated = @ts || Time.now.utc
if self.ext_verifier.present?
@ext = self.ext_verifier.new(
raw_body: request.body,
algorithm: self.mac_algorithm
).calculate
end
@signature = Signature.new(
secret: self.mac_key,
algorithm: self.mac_algorithm,
nonce: self.nonce,
method: request.header.request_method,
request_uri: request.header.create_query_uri,
host: request.header.request_uri.host,
port: request.header.request_uri.port,
ts: @ts_generated,
ext: @ext
).calculate
request.header['Authorization'] = authorization_header
end
private
def authorization_header
header = "MAC id=\"#{access_token}\""
header << ", nonce=\"#{nonce}\""
header << ", ts=\"#{@ts_generated.to_i}\""
header << ", mac=\"#{signature}\""
header << ", ext=\"#{ext}\"" if @ext.present?
header
end
def generate_nonce
[
(Time.now.utc - @issued_at).to_i,
SecureRandom.hex
].join(':')
end
end
end
end
end
require 'rack/oauth2/access_token/mac/verifier'
require 'rack/oauth2/access_token/mac/sha256_hex_verifier'
require 'rack/oauth2/access_token/mac/signature'
rack-oauth2-1.9.3/lib/rack/oauth2/access_token/mtls.rb 0000644 0000041 0000041 00000000565 13410611536 022537 0 ustar www-data www-data module Rack
module OAuth2
class AccessToken
class MTLS < Bearer
attr_required :private_key, :certificate
def initialize(attributes = {})
super
self.token_type = :bearer
httpclient.ssl_config.client_key = private_key
httpclient.ssl_config.client_cert = certificate
end
end
end
end
end
rack-oauth2-1.9.3/lib/rack/oauth2/access_token/bearer.rb 0000644 0000041 0000041 00000000661 13410611536 023015 0 ustar www-data www-data module Rack
module OAuth2
class AccessToken
class Bearer < AccessToken
def authenticate(request)
request.header["Authorization"] = "Bearer #{access_token}"
end
def to_mtls(attributes = {})
(required_attributes + optional_attributes).each do |key|
attributes[key] = self.send(key)
end
MTLS.new attributes
end
end
end
end
end
rack-oauth2-1.9.3/lib/rack/oauth2/access_token/legacy.rb 0000644 0000041 0000041 00000000632 13410611536 023017 0 ustar www-data www-data module Rack
module OAuth2
class AccessToken
class Legacy < AccessToken
def initialize(attributes = {})
super
self.expires_in = (
self.expires_in ||
attributes[:expires]
).try(:to_i)
end
def authenticate(request)
request.header["Authorization"] = "OAuth #{access_token}"
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/access_token/authenticator.rb 0000644 0000041 0000041 00000001107 13410611536 024423 0 ustar www-data www-data module Rack
module OAuth2
class AccessToken
class Authenticator
def initialize(token)
@token = token
end
# Callback called in HTTPClient (before sending a request)
# request:: HTTP::Message
def filter_request(request)
@token.authenticate(request)
end
# Callback called in HTTPClient (after received a response)
# response:: HTTP::Message
# request:: HTTP::Message
def filter_response(response, request)
# nothing to do
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/ 0000755 0000041 0000041 00000000000 13410611536 020072 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/server/abstract.rb 0000644 0000041 0000041 00000000266 13410611536 022226 0 ustar www-data www-data require 'rack/oauth2/server/abstract/handler'
require 'rack/oauth2/server/abstract/request'
require 'rack/oauth2/server/abstract/response'
require 'rack/oauth2/server/abstract/error' rack-oauth2-1.9.3/lib/rack/oauth2/server/authorize/ 0000755 0000041 0000041 00000000000 13410611536 022104 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/server/authorize/extension.rb 0000644 0000041 0000041 00000000427 13410611536 024450 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Authorize
module Extension
# Define your extension in this namespace and load it explicitly.
# extension/code_and_token.rb would be good example for you.
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/authorize/error.rb 0000644 0000041 0000041 00000006315 13410611536 023567 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Authorize
module ErrorHandler
def self.included(klass)
klass.send :attr_accessor, :redirect_uri, :state, :protocol_params_location
end
def protocol_params
super.merge(state: state)
end
def redirect?
redirect_uri.present? &&
protocol_params_location.present?
end
def finish
if redirect?
super do |response|
response.redirect Util.redirect_uri(redirect_uri, protocol_params_location, protocol_params)
end
else
raise self
end
end
end
class BadRequest < Abstract::BadRequest
include ErrorHandler
end
class ServerError < Abstract::ServerError
include ErrorHandler
end
class TemporarilyUnavailable < Abstract::TemporarilyUnavailable
include ErrorHandler
end
module ErrorMethods
DEFAULT_DESCRIPTION = {
invalid_request: "The request is missing a required parameter, includes an unsupported parameter or parameter value, or is otherwise malformed.",
unauthorized_client: "The client is not authorized to use the requested response type.",
access_denied: "The end-user or authorization server denied the request.",
unsupported_response_type: "The requested response type is not supported by the authorization server.",
invalid_scope: "The requested scope is invalid, unknown, or malformed.",
server_error: "Internal Server Error",
temporarily_unavailable: "Service Unavailable"
}
def self.included(klass)
DEFAULT_DESCRIPTION.each do |error, default_description|
case error
when :server_error, :temporarily_unavailable
# NOTE: defined below
else
klass.class_eval <<-ERROR
def #{error}!(description = "#{default_description}", options = {})
bad_request! :#{error}, description, options
end
ERROR
end
end
end
def bad_request!(error = :bad_request, description = nil, options = {})
error! BadRequest, error, description, options
end
def server_error!(description = DEFAULT_DESCRIPTION[:server_error], options = {})
error! ServerError, :server_error, description, options
end
def temporarily_unavailable!(description = DEFAULT_DESCRIPTION[:temporarily_unavailable], options = {})
error! TemporarilyUnavailable, :temporarily_unavailable, description, options
end
private
def error!(klass, error, description, options)
exception = klass.new error, description, options
exception.protocol_params_location = error_params_location
exception.state = state
exception.redirect_uri = verified_redirect_uri
raise exception
end
end
Request.send :include, ErrorMethods
end
end
end
end
rack-oauth2-1.9.3/lib/rack/oauth2/server/authorize/token.rb 0000644 0000041 0000041 00000001700 13410611536 023547 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Authorize
class Token < Abstract::Handler
def _call(env)
@request = Request.new env
@response = Response.new request
super
end
class Request < Authorize::Request
def initialize(env)
super
@response_type = :token
attr_missing!
end
def error_params_location
:fragment
end
end
class Response < Authorize::Response
attr_required :access_token
def protocol_params
super.merge(
access_token.token_response.delete_if do |k, v|
k == :refresh_token
end
)
end
def protocol_params_location
:fragment
end
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/authorize/code.rb 0000644 0000041 0000041 00000001565 13410611536 023352 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Authorize
class Code < Abstract::Handler
def _call(env)
@request = Request.new env
@response = Response.new request
super
end
class Request < Authorize::Request
include Server::Extension::PKCE::AuthorizationRequest
def initialize(env)
super
@response_type = :code
attr_missing!
end
def error_params_location
:query
end
end
class Response < Authorize::Response
attr_required :code
def protocol_params
super.merge(code: code)
end
def protocol_params_location
:query
end
end
end
end
end
end
end
rack-oauth2-1.9.3/lib/rack/oauth2/server/authorize/extension/ 0000755 0000041 0000041 00000000000 13410611536 024120 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/server/authorize/extension/code_and_token.rb 0000644 0000041 0000041 00000001770 13410611536 027406 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Authorize
module Extension
class CodeAndToken < Abstract::Handler
class << self
def response_type_for?(response_type)
response_type.split.sort == ['code', 'token']
end
end
def _call(env)
@request = Request.new env
@response = Response.new request
super
end
class Request < Authorize::Token::Request
include Server::Extension::PKCE::AuthorizationRequest
def initialize(env)
super
@response_type = [:code, :token]
attr_missing!
end
end
class Response < Authorize::Token::Response
attr_required :code
def protocol_params
super.merge(code: code)
end
end
end
end
end
end
end
end
rack-oauth2-1.9.3/lib/rack/oauth2/server/extension.rb 0000644 0000041 0000041 00000000140 13410611536 022426 0 ustar www-data www-data require 'rack/oauth2/server/extension/pkce'
require 'rack/oauth2/server/extension/response_mode' rack-oauth2-1.9.3/lib/rack/oauth2/server/abstract/ 0000755 0000041 0000041 00000000000 13410611536 021675 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/server/abstract/request.rb 0000644 0000041 0000041 00000001427 13410611536 023716 0 ustar www-data www-data module Rack
module OAuth2
module Server
module Abstract
class Request < Rack::Request
include AttrRequired, AttrOptional
attr_required :client_id
attr_optional :scope
def initialize(env)
super
@client_id ||= params['client_id']
@scope = Array(params['scope'].to_s.split(' '))
end
def attr_missing!
if params['client_id'].present? && @client_id != params['client_id']
invalid_request! 'Multiple client credentials are provided.'
end
super
rescue AttrRequired::AttrMissing => e
invalid_request! e.message, state: @state, redirect_uri: @redirect_uri
end
end
end
end
end
end
rack-oauth2-1.9.3/lib/rack/oauth2/server/abstract/error.rb 0000644 0000041 0000041 00000004072 13410611536 023356 0 ustar www-data www-data module Rack
module OAuth2
module Server
module Abstract
class Error < StandardError
attr_accessor :status, :error, :description, :uri, :realm
def initialize(status, error, description = nil, options = {})
@status = status
@error = error
@description = description
@uri = options[:uri]
@realm = options[:realm]
super [error, description].compact.join(' :: ')
end
def protocol_params
{
error: error,
error_description: description,
error_uri: uri
}
end
def finish
response = Rack::Response.new
response.status = status
yield response if block_given?
unless response.redirect?
response.header['Content-Type'] = 'application/json'
response.write Util.compact_hash(protocol_params).to_json
end
response.finish
end
end
class BadRequest < Error
def initialize(error = :bad_request, description = nil, options = {})
super 400, error, description, options
end
end
class Unauthorized < Error
def initialize(error = :unauthorized, description = nil, options = {})
super 401, error, description, options
end
end
class Forbidden < Error
def initialize(error = :forbidden, description = nil, options = {})
super 403, error, description, options
end
end
class ServerError < Error
def initialize(error = :server_error, description = nil, options = {})
super 500, error, description, options
end
end
class TemporarilyUnavailable < Error
def initialize(error = :temporarily_unavailable, description = nil, options = {})
super 503, error, description, options
end
end
end
end
end
end
rack-oauth2-1.9.3/lib/rack/oauth2/server/abstract/handler.rb 0000644 0000041 0000041 00000001456 13410611536 023645 0 ustar www-data www-data module Rack
module OAuth2
module Server
module Abstract
class Handler
attr_accessor :authenticator, :request, :response
def initialize(&authenticator)
@authenticator = authenticator
end
def call(env)
# NOTE:
# Rack middleware is initialized only on the first request of the process.
# So any instance variables are acts like class variables, and modifying them in call() isn't thread-safe.
# ref.) http://stackoverflow.com/questions/23028226/rack-middleware-and-thread-safety
dup._call(env)
end
def _call(env)
@authenticator.call(@request, @response) if @authenticator
@response
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/abstract/response.rb 0000644 0000041 0000041 00000000420 13410611536 024054 0 ustar www-data www-data module Rack
module OAuth2
module Server
module Abstract
class Response < Rack::Response
include AttrRequired, AttrOptional
def initialize(request)
super([], 200, {})
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/token/ 0000755 0000041 0000041 00000000000 13410611536 021212 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/server/token/authorization_code.rb 0000644 0000041 0000041 00000001333 13410611536 025431 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Token
class AuthorizationCode < Abstract::Handler
def _call(env)
@request = Request.new(env)
@response = Response.new(request)
super
end
class Request < Token::Request
include Server::Extension::PKCE::TokenRequest
attr_required :code
attr_optional :redirect_uri
def initialize(env)
super
@grant_type = :authorization_code
@code = params['code']
@redirect_uri = params['redirect_uri']
attr_missing!
end
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/token/saml2_bearer.rb 0000644 0000041 0000041 00000001156 13410611536 024100 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Token
class SAML2Bearer < Abstract::Handler
def _call(env)
@request = Request.new env
@response = Response.new request
super
end
class Request < Token::Request
attr_required :assertion
attr_optional :client_id
def initialize(env)
super
@grant_type = URN::GrantType::SAML2_BEARER
@assertion = params['assertion']
attr_missing!
end
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/token/refresh_token.rb 0000644 0000041 0000041 00000001115 13410611536 024373 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Token
class RefreshToken < Abstract::Handler
def _call(env)
@request = Request.new(env)
@response = Response.new(request)
super
end
class Request < Token::Request
attr_required :refresh_token
def initialize(env)
super
@grant_type = :refresh_token
@refresh_token = params['refresh_token']
attr_missing!
end
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/token/extension.rb 0000644 0000041 0000041 00000000426 13410611536 023555 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Token
module Extension
# Define your extension in this namespace and load it explicitly.
# extension/assertion/example.rb would be good example for you.
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/token/error.rb 0000644 0000041 0000041 00000004626 13410611536 022700 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Token
class BadRequest < Abstract::BadRequest
end
class Unauthorized < Abstract::Unauthorized
def finish
super do |response|
response.header['WWW-Authenticate'] = 'Basic realm="OAuth2 Token Endpoint"'
end
end
end
module ErrorMethods
DEFAULT_DESCRIPTION = {
invalid_request: "The request is missing a required parameter, includes an unsupported parameter or parameter value, repeats a parameter, includes multiple credentials, utilizes more than one mechanism for authenticating the client, or is otherwise malformed.",
invalid_client: "The client identifier provided is invalid, the client failed to authenticate, the client did not include its credentials, provided multiple client credentials, or used unsupported credentials type.",
invalid_grant: "The provided access grant is invalid, expired, or revoked (e.g. invalid assertion, expired authorization token, bad end-user password credentials, or mismatching authorization code and redirection URI).",
unauthorized_client: "The authenticated client is not authorized to use the access grant type provided.",
unsupported_grant_type: "The access grant included - its type or another attribute - is not supported by the authorization server.",
invalid_scope: "The requested scope is invalid, unknown, malformed, or exceeds the previously granted scope."
}
def self.included(klass)
DEFAULT_DESCRIPTION.each do |error, default_description|
error_method = if error == :invalid_client
:unauthorized!
else
:bad_request!
end
klass.class_eval <<-ERROR
def #{error}!(description = "#{default_description}", options = {})
#{error_method} :#{error}, description, options
end
ERROR
end
end
def bad_request!(error, description = nil, options = {})
raise BadRequest.new(error, description, options)
end
def unauthorized!(error, description = nil, options = {})
raise Unauthorized.new(error, description, options)
end
end
Request.send :include, ErrorMethods
end
end
end
end
rack-oauth2-1.9.3/lib/rack/oauth2/server/token/jwt_bearer.rb 0000644 0000041 0000041 00000001152 13410611536 023662 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Token
class JWTBearer < Abstract::Handler
def _call(env)
@request = Request.new env
@response = Response.new request
super
end
class Request < Token::Request
attr_required :assertion
attr_optional :client_id
def initialize(env)
super
@grant_type = URN::GrantType::JWT_BEARER
@assertion = params['assertion']
attr_missing!
end
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/token/client_credentials.rb 0000644 0000041 0000041 00000000763 13410611536 025400 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Token
class ClientCredentials < Abstract::Handler
def _call(env)
@request = Request.new(env)
@response = Response.new(request)
super
end
class Request < Token::Request
def initialize(env)
super
@grant_type = :client_credentials
attr_missing!
end
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/token/extension/ 0000755 0000041 0000041 00000000000 13410611536 023226 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/server/token/extension/example.rb 0000644 0000041 0000041 00000001604 13410611536 025207 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Token
module Extension
class Example < Abstract::Handler
GRANT_TYPE_URN = 'urn:ietf:params:oauth:grant-type:example'
class << self
def grant_type_for?(grant_type)
grant_type == GRANT_TYPE_URN
end
end
def _call(env)
@request = Request.new env
@response = Response.new request
super
end
class Request < Token::Request
attr_required :assertion
attr_optional :client_id
def initialize(env)
super
@grant_type = GRANT_TYPE_URN
@assertion = params['assertion']
attr_missing!
end
end
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/token/password.rb 0000644 0000041 0000041 00000001156 13410611536 023404 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Token
class Password < Abstract::Handler
def _call(env)
@request = Request.new(env)
@response = Response.new(request)
super
end
class Request < Token::Request
attr_required :username, :password
def initialize(env)
super
@grant_type = :password
@username = params['username']
@password = params['password']
attr_missing!
end
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/rails/ 0000755 0000041 0000041 00000000000 13410611536 021204 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/server/rails/response_ext.rb 0000644 0000041 0000041 00000001527 13410611536 024254 0 ustar www-data www-data module Rack
module OAuth2
module Server
module Rails
module ResponseExt
def redirect?
ensure_finish do
@response.redirect?
end
end
def location
ensure_finish do
super
end
end
def json
ensure_finish do
@response.body
end
end
def header
ensure_finish do
@header
end
end
def finish
@finished = true
super
end
private
def finished?
!!@finished
end
def ensure_finish
@status, @header, @response = finish unless finished?
yield
end
end
end
end
end
end
rack-oauth2-1.9.3/lib/rack/oauth2/server/rails/authorize.rb 0000644 0000041 0000041 00000002030 13410611536 023536 0 ustar www-data www-data module Rack
module OAuth2
module Server
module Rails
class Authorize < Server::Authorize
def initialize(app)
super()
@app = app
end
def _call(env)
prepare_oauth_env env
@app.call env
rescue Rack::OAuth2::Server::Abstract::Error => e
e.finish
end
private
def prepare_oauth_env(env)
response_type = response_type_for(
Server::Authorize::Request.new(env)
).new
response_type._call(env)
response_type.response.extend ResponseExt
env[REQUEST] = response_type.request
env[RESPONSE] = response_type.response
rescue Rack::OAuth2::Server::Abstract::Error => e
env[ERROR] = e
end
module ResponseExt
include Rails::ResponseExt
def approve!
super
finish
end
end
end
end
end
end
end
rack-oauth2-1.9.3/lib/rack/oauth2/server/authorize.rb 0000644 0000041 0000041 00000007120 13410611536 022431 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Authorize < Abstract::Handler
def _call(env)
request = Request.new(env)
response_type_for(request).new(&@authenticator)._call(env).finish
rescue Rack::OAuth2::Server::Abstract::Error => e
e.finish
end
private
def response_type_for(request)
response_type = request.params['response_type'].to_s
case response_type
when 'code'
Code
when 'token'
Token
when ''
request.attr_missing!
else
extensions.detect do |extension|
extension.response_type_for? response_type
end || request.unsupported_response_type!
end
end
def extensions
Extension.constants.sort.collect do |key|
Extension.const_get key
end
end
class Request < Abstract::Request
include Server::Extension::ResponseMode::AuthorizationRequest
attr_required :response_type
attr_optional :redirect_uri, :state
attr_accessor :verified_redirect_uri
def initialize(env)
super
# NOTE: Raise before redirect_uri is saved not to redirect back to unverified redirect_uri.
invalid_request! '"client_id" missing' if client_id.blank?
@redirect_uri = Util.parse_uri(params['redirect_uri']) if params['redirect_uri']
@response_mode = params['response_mode']
@state = params['state']
end
def verify_redirect_uri!(pre_registered, allow_partial_match = false)
@verified_redirect_uri = if redirect_uri.present?
verified = Array(pre_registered).any? do |_pre_registered_|
if allow_partial_match
Util.uri_match?(_pre_registered_, redirect_uri)
else
_pre_registered_.to_s == redirect_uri.to_s
end
end
if verified
redirect_uri
else
invalid_request! '"redirect_uri" mismatch'
end
elsif pre_registered.present? && Array(pre_registered).size == 1 && !allow_partial_match
Array(pre_registered).first
else
invalid_request! '"redirect_uri" missing'
end
self.verified_redirect_uri.to_s
end
def error_params_location
nil # => All errors are raised immediately and no error response are returned to client.
end
end
class Response < Abstract::Response
attr_required :redirect_uri
attr_optional :state, :session_state, :approval
def initialize(request)
@state = request.state
super
end
def approved?
@approval
end
def approve!
@approval = true
end
def protocol_params
{state: state, session_state: session_state}
end
def redirect_uri_with_credentials
Util.redirect_uri(redirect_uri, protocol_params_location, protocol_params)
end
def finish
if approved?
attr_missing!
redirect redirect_uri_with_credentials
end
super
end
end
end
end
end
end
require 'rack/oauth2/server/authorize/code'
require 'rack/oauth2/server/authorize/token'
require 'rack/oauth2/server/authorize/extension'
require 'rack/oauth2/server/authorize/error'
rack-oauth2-1.9.3/lib/rack/oauth2/server/resource.rb 0000644 0000041 0000041 00000002425 13410611536 022251 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Resource < Abstract::Handler
ACCESS_TOKEN = 'rack.oauth2.access_token'
DEFAULT_REALM = 'Protected by OAuth 2.0'
attr_accessor :realm, :request
def initialize(app, realm = nil, &authenticator)
@app = app
@realm = realm
super(&authenticator)
end
def _call(env)
if request.oauth2?
access_token = authenticate! request.setup!
env[ACCESS_TOKEN] = access_token
end
@app.call(env)
rescue Rack::OAuth2::Server::Abstract::Error => e
e.realm ||= realm
e.finish
end
private
def authenticate!(request)
@authenticator.call(request)
end
class Request < Rack::Request
attr_reader :access_token
def initialize(env)
@env = env
@auth_header = Rack::Auth::AbstractRequest.new(env)
end
def setup!
raise 'Define me!'
end
def oauth2?
raise 'Define me!'
end
end
end
end
end
end
require 'rack/oauth2/server/resource/error'
require 'rack/oauth2/server/resource/bearer'
require 'rack/oauth2/server/resource/mac'
rack-oauth2-1.9.3/lib/rack/oauth2/server/token.rb 0000644 0000041 0000041 00000005007 13410611536 021541 0 ustar www-data www-data require 'rack/auth/basic'
module Rack
module OAuth2
module Server
class Token < Abstract::Handler
def _call(env)
request = Request.new(env)
grant_type_for(request).new(&@authenticator)._call(env).finish
rescue Rack::OAuth2::Server::Abstract::Error => e
e.finish
end
private
def grant_type_for(request)
case request.grant_type
when 'authorization_code'
AuthorizationCode
when 'password'
Password
when 'client_credentials'
ClientCredentials
when 'refresh_token'
RefreshToken
when URN::GrantType::JWT_BEARER
JWTBearer
when URN::GrantType::SAML2_BEARER
SAML2Bearer
when ''
request.attr_missing!
else
extensions.detect do |extension|
extension.grant_type_for? request.grant_type
end || request.unsupported_grant_type!
end
end
def extensions
Extension.constants.sort.collect do |key|
Extension.const_get key
end
end
class Request < Abstract::Request
attr_required :grant_type
attr_optional :client_secret
def initialize(env)
auth = Rack::Auth::Basic::Request.new(env)
if auth.provided? && auth.basic?
@client_id, @client_secret = auth.credentials
super
else
super
@client_secret = params['client_secret']
end
@grant_type = params['grant_type'].to_s
end
end
class Response < Abstract::Response
attr_required :access_token
def protocol_params
access_token.token_response
end
def finish
attr_missing!
write Util.compact_hash(protocol_params).to_json
header['Content-Type'] = 'application/json'
header['Cache-Control'] = 'no-store'
header['Pragma'] = 'no-cache'
super
end
end
end
end
end
end
require 'rack/oauth2/server/token/authorization_code'
require 'rack/oauth2/server/token/password'
require 'rack/oauth2/server/token/client_credentials'
require 'rack/oauth2/server/token/refresh_token'
require 'rack/oauth2/server/token/jwt_bearer'
require 'rack/oauth2/server/token/saml2_bearer'
require 'rack/oauth2/server/token/extension'
require 'rack/oauth2/server/token/error'
rack-oauth2-1.9.3/lib/rack/oauth2/server/rails.rb 0000644 0000041 0000041 00000000465 13410611536 021536 0 ustar www-data www-data module Rack
module OAuth2
module Server
module Rails
REQUEST = 'rack_oauth2.request'
RESPONSE = 'rack_oauth2.response'
ERROR = 'rack_oauth2.error'
end
end
end
end
require 'rack/oauth2/server/rails/response_ext'
require 'rack/oauth2/server/rails/authorize'
rack-oauth2-1.9.3/lib/rack/oauth2/server/resource/ 0000755 0000041 0000041 00000000000 13410611536 021721 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/server/resource/mac/ 0000755 0000041 0000041 00000000000 13410611536 022461 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/server/resource/mac/error.rb 0000644 0000041 0000041 00000001037 13410611536 024140 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Resource
class MAC
class Unauthorized < Resource::Unauthorized
def scheme
:MAC
end
end
module ErrorMethods
include Resource::ErrorMethods
def unauthorized!(error = nil, description = nil, options = {})
raise Unauthorized.new(error, description, options)
end
end
Request.send :include, ErrorMethods
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/resource/mac.rb 0000644 0000041 0000041 00000001615 13410611536 023011 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Resource
class MAC < Resource
def _call(env)
self.request = Request.new(env)
super
end
private
class Request < Resource::Request
attr_reader :nonce, :ts, :ext, :signature
def setup!
auth_params = Rack::Auth::Digest::Params.parse(@auth_header.params).with_indifferent_access
@access_token = auth_params[:id]
@nonce = auth_params[:nonce]
@ts = auth_params[:ts]
@ext = auth_params[:ext]
@signature = auth_params[:mac]
self
end
def oauth2?
@auth_header.provided? && @auth_header.scheme.to_s == 'mac'
end
end
end
end
end
end
end
require 'rack/oauth2/server/resource/mac/error'
rack-oauth2-1.9.3/lib/rack/oauth2/server/resource/bearer.rb 0000644 0000041 0000041 00000002304 13410611536 023505 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Resource
class Bearer < Resource
def _call(env)
self.request = Request.new(env)
super
end
private
class Request < Resource::Request
def setup!
tokens = [access_token_in_header, access_token_in_payload].compact
@access_token = case Array(tokens).size
when 1
tokens.first
else
invalid_request!('Both Authorization header and payload includes access token.')
end
self
end
def oauth2?
(access_token_in_header || access_token_in_payload).present?
end
def access_token_in_header
if @auth_header.provided? && !@auth_header.parts.first.nil? && @auth_header.scheme.to_s == 'bearer'
@auth_header.params
else
nil
end
end
def access_token_in_payload
params['access_token']
end
end
end
end
end
end
end
require 'rack/oauth2/server/resource/bearer/error'
rack-oauth2-1.9.3/lib/rack/oauth2/server/resource/error.rb 0000644 0000041 0000041 00000005317 13410611536 023405 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Resource
class BadRequest < Abstract::BadRequest
end
class Unauthorized < Abstract::Unauthorized
def scheme
raise 'Define me!'
end
def finish
super do |response|
self.realm ||= DEFAULT_REALM
header = response.header['WWW-Authenticate'] = "#{scheme} realm=\"#{realm}\""
if ErrorMethods::DEFAULT_DESCRIPTION.keys.include?(error)
header << ", error=\"#{error}\""
header << ", error_description=\"#{description}\"" if description.present?
header << ", error_uri=\"#{uri}\"" if uri.present?
end
end
end
end
class Forbidden < Abstract::Forbidden
attr_accessor :scope
def initialize(error = :forbidden, description = nil, options = {})
super
@scope = options[:scope]
end
def protocol_params
super.merge(scope: Array(scope).join(' '))
end
end
module ErrorMethods
DEFAULT_DESCRIPTION = {
invalid_request: "The request is missing a required parameter, includes an unsupported parameter or parameter value, repeats the same parameter, uses more than one method for including an access token, or is otherwise malformed.",
invalid_token: "The access token provided is expired, revoked, malformed or invalid for other reasons.",
insufficient_scope: "The request requires higher privileges than provided by the access token."
}
def self.included(klass)
DEFAULT_DESCRIPTION.each do |error, default_description|
error_method = case error
when :invalid_request
:bad_request!
when :insufficient_scope
:forbidden!
else
:unauthorized!
end
klass.class_eval <<-ERROR
def #{error}!(description = "#{default_description}", options = {})
#{error_method} :#{error}, description, options
end
ERROR
end
end
def bad_request!(error, description = nil, options = {})
raise BadRequest.new(error, description, options)
end
def unauthorized!(error = nil, description = nil, options = {})
raise 'Define me!'
end
def forbidden!(error, description = nil, options = {})
raise Forbidden.new(error, description, options)
end
end
Request.send :include, ErrorMethods
end
end
end
end
rack-oauth2-1.9.3/lib/rack/oauth2/server/resource/bearer/ 0000755 0000041 0000041 00000000000 13410611536 023161 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/server/resource/bearer/error.rb 0000644 0000041 0000041 00000001045 13410611536 024637 0 ustar www-data www-data module Rack
module OAuth2
module Server
class Resource
class Bearer
class Unauthorized < Resource::Unauthorized
def scheme
:Bearer
end
end
module ErrorMethods
include Resource::ErrorMethods
def unauthorized!(error = nil, description = nil, options = {})
raise Unauthorized.new(error, description, options)
end
end
Request.send :include, ErrorMethods
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/extension/ 0000755 0000041 0000041 00000000000 13410611536 022106 5 ustar www-data www-data rack-oauth2-1.9.3/lib/rack/oauth2/server/extension/response_mode.rb 0000644 0000041 0000041 00000000645 13410611536 025302 0 ustar www-data www-data module Rack
module OAuth2
module Server
module Extension
module ResponseMode
module AuthorizationRequest
def self.included(klass)
klass.send :attr_optional, :response_mode
end
def initialize(env)
super
@response_mode = params['response_mode']
end
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server/extension/pkce.rb 0000644 0000041 0000041 00000002572 13410611536 023363 0 ustar www-data www-data module Rack
module OAuth2
module Server
module Extension
module PKCE
module AuthorizationRequest
def self.included(klass)
klass.send :attr_optional, :code_challenge, :code_challenge_method
end
def initialize(env)
super
@code_challenge = params['code_challenge']
@code_challenge_method = params['code_challenge_method']
end
end
module TokenRequest
def self.included(klass)
klass.send :attr_optional, :code_verifier
end
def initialize(env)
super
@code_verifier = params['code_verifier']
end
def verify_code_verifier!(code_challenge, code_challenge_method = :S256)
if code_verifier.present? || code_challenge.present?
case code_challenge_method.try(:to_sym)
when :S256
code_challenge == Util.urlsafe_base64_encode(
OpenSSL::Digest::SHA256.digest(code_verifier.to_s)
) or invalid_grant!
when :plain
code_challenge == code_verifier or invalid_grant!
else
invalid_grant!
end
end
end
end
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/util.rb 0000644 0000041 0000041 00000003042 13410611536 020065 0 ustar www-data www-data require 'base64'
module Rack
module OAuth2
module Util
class << self
def rfc3986_encode(text)
URI.encode(text, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
end
def base64_encode(text)
Base64.encode64(text).delete("\n")
end
def urlsafe_base64_encode(text)
Base64.urlsafe_encode64(text, padding: false)
end
def compact_hash(hash)
hash.reject do |key, value|
value.blank?
end
end
def parse_uri(uri)
case uri
when URI::Generic
uri
when String
URI.parse(uri)
else
raise "Invalid format of URI is given."
end
end
def redirect_uri(base_uri, location, params)
redirect_uri = parse_uri base_uri
case location
when :query
redirect_uri.query = [redirect_uri.query, Util.compact_hash(params).to_query].compact.join('&')
when :fragment
redirect_uri.fragment = Util.compact_hash(params).to_query
end
redirect_uri.to_s
end
def uri_match?(base, given)
base = parse_uri(base)
given = parse_uri(given)
base.path = '/' if base.path.blank?
given.path = '/' if given.path.blank?
[:scheme, :host, :port].all? do |key|
base.send(key) == given.send(key)
end && !!(/^#{base.path}/ =~ given.path)
rescue
false
end
end
end
end
end rack-oauth2-1.9.3/lib/rack/oauth2/server.rb 0000644 0000041 0000041 00000000340 13410611536 020414 0 ustar www-data www-data require 'rack/oauth2/server/abstract'
require 'rack/oauth2/server/extension'
require 'rack/oauth2/server/authorize'
require 'rack/oauth2/server/token'
require 'rack/oauth2/server/resource'
require 'rack/oauth2/server/rails'
rack-oauth2-1.9.3/lib/rack/oauth2/access_token.rb 0000644 0000041 0000041 00000002423 13410611536 021553 0 ustar www-data www-data module Rack
module OAuth2
class AccessToken
include AttrRequired, AttrOptional
attr_required :access_token, :token_type, :httpclient
attr_optional :refresh_token, :expires_in, :scope
attr_accessor :raw_attributes
delegate :get, :patch, :post, :put, :delete, to: :httpclient
alias_method :to_s, :access_token
def initialize(attributes = {})
(required_attributes + optional_attributes).each do |key|
self.send :"#{key}=", attributes[key]
end
@raw_attributes = attributes
@token_type = self.class.name.demodulize.underscore.to_sym
@httpclient = Rack::OAuth2.http_client("#{self.class} (#{VERSION})") do |config|
config.request_filter << Authenticator.new(self)
end
attr_missing!
end
def token_response(options = {})
{
access_token: access_token,
refresh_token: refresh_token,
token_type: token_type,
expires_in: expires_in,
scope: Array(scope).join(' ')
}
end
end
end
end
require 'rack/oauth2/access_token/authenticator'
require 'rack/oauth2/access_token/bearer'
require 'rack/oauth2/access_token/mac'
require 'rack/oauth2/access_token/legacy'
require 'rack/oauth2/access_token/mtls'
rack-oauth2-1.9.3/README.rdoc 0000644 0000041 0000041 00000004106 13410611536 015503 0 ustar www-data www-data = rack-oauth2
OAuth 2.0 Server & Client Library.
Both Bearer and MAC token type are supported.
{
}[http://travis-ci.org/nov/rack-oauth2]
The OAuth 2.0 Authorization Framework (RFC 6749)
http://www.rfc-editor.org/rfc/rfc6749.txt
The OAuth 2.0 Authorization Framework: Bearer Token Usage (RFC 6750)
http://tools.ietf.org/html/draft-ietf-oauth-v2-bearer-06
HTTP Authentication: MAC Access Authentication (draft 01)
http://tools.ietf.org/html/draft-ietf-oauth-v2-http-mac-01
== Installation
gem install rack-oauth2
== Resources
* View Source on GitHub (https://github.com/nov/rack-oauth2)
* Docs on GitHub (https://github.com/nov/rack-oauth2/wiki)
* Report Issues on GitHub (https://github.com/nov/rack-oauth2/issues)
== Sample Server Application (Rails3)
=== Bearer
Running on Heroku
https://rack-oauth2-sample.heroku.com
Source on GitHub
https://github.com/nov/rack-oauth2-sample
=== MAC
Running on Heroku
https://rack-oauth2-sample-mac.heroku.com
Source on GitHub
https://github.com/nov/rack-oauth2-sample-mac
== Sample Client
=== Common between Bearer and MAC
Authorization Request (request_type: 'code' and 'token')
https://gist.github.com/862393
Token Request (grant_type: 'client_credentials', 'password', 'authorization_code' and 'refresh_token')
https://gist.github.com/883541
=== Bearer
Resource Request (request both for resource owner resource and for client resource)
https://gist.github.com/883575
=== MAC
Resource Request (request both for resource owner resource and for client resource)
https://gist.github.com/933885
== Note on Patches/Pull Requests
* Fork the project.
* Make your feature addition or bug fix.
* Add tests for it. This is important so I don't break it in a
future version unintentionally.
* Commit, do not mess with rakefile, version, or history.
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
* Send me a pull request. Bonus points for topic branches.
== Copyright
Copyright (c) 2010 nov matake. See LICENSE for details.
rack-oauth2-1.9.3/Gemfile 0000644 0000041 0000041 00000000140 13410611536 015162 0 ustar www-data www-data source 'https://rubygems.org'
platforms :jruby do
gem 'jruby-openssl', '>= 0.7'
end
gemspec
rack-oauth2-1.9.3/VERSION 0000644 0000041 0000041 00000000006 13410611536 014740 0 ustar www-data www-data 1.9.3