rack-oauth2-revibe 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.gitignore +22 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +7 -0
- data/LICENSE +20 -0
- data/README.rdoc +78 -0
- data/Rakefile +25 -0
- data/VERSION +1 -0
- data/lib/rack/oauth2.rb +67 -0
- data/lib/rack/oauth2/access_token.rb +36 -0
- data/lib/rack/oauth2/access_token/authenticator.rb +24 -0
- data/lib/rack/oauth2/access_token/bearer.rb +11 -0
- data/lib/rack/oauth2/access_token/legacy.rb +23 -0
- data/lib/rack/oauth2/access_token/mac.rb +103 -0
- data/lib/rack/oauth2/access_token/mac/sha256_hex_verifier.rb +17 -0
- data/lib/rack/oauth2/access_token/mac/signature.rb +34 -0
- data/lib/rack/oauth2/access_token/mac/verifier.rb +44 -0
- data/lib/rack/oauth2/client.rb +139 -0
- data/lib/rack/oauth2/client/error.rb +14 -0
- data/lib/rack/oauth2/client/grant.rb +30 -0
- data/lib/rack/oauth2/client/grant/authorization_code.rb +12 -0
- data/lib/rack/oauth2/client/grant/client_credentials.rb +10 -0
- data/lib/rack/oauth2/client/grant/facebook_token.rb +12 -0
- data/lib/rack/oauth2/client/grant/password.rb +11 -0
- data/lib/rack/oauth2/client/grant/refresh_token.rb +11 -0
- data/lib/rack/oauth2/debugger.rb +3 -0
- data/lib/rack/oauth2/debugger/request_filter.rb +30 -0
- data/lib/rack/oauth2/server.rb +4 -0
- data/lib/rack/oauth2/server/abstract.rb +4 -0
- data/lib/rack/oauth2/server/abstract/error.rb +69 -0
- data/lib/rack/oauth2/server/abstract/handler.rb +20 -0
- data/lib/rack/oauth2/server/abstract/request.rb +29 -0
- data/lib/rack/oauth2/server/abstract/response.rb +15 -0
- data/lib/rack/oauth2/server/authorize.rb +117 -0
- data/lib/rack/oauth2/server/authorize/code.rb +39 -0
- data/lib/rack/oauth2/server/authorize/error.rb +71 -0
- data/lib/rack/oauth2/server/authorize/extension.rb +12 -0
- data/lib/rack/oauth2/server/authorize/extension/code_and_token.rb +39 -0
- data/lib/rack/oauth2/server/authorize/token.rb +43 -0
- data/lib/rack/oauth2/server/resource.rb +55 -0
- data/lib/rack/oauth2/server/resource/bearer.rb +47 -0
- data/lib/rack/oauth2/server/resource/bearer/error.rb +24 -0
- data/lib/rack/oauth2/server/resource/error.rb +81 -0
- data/lib/rack/oauth2/server/resource/mac.rb +36 -0
- data/lib/rack/oauth2/server/resource/mac/error.rb +24 -0
- data/lib/rack/oauth2/server/token.rb +87 -0
- data/lib/rack/oauth2/server/token/authorization_code.rb +28 -0
- data/lib/rack/oauth2/server/token/client_credentials.rb +23 -0
- data/lib/rack/oauth2/server/token/error.rb +54 -0
- data/lib/rack/oauth2/server/token/extension.rb +12 -0
- data/lib/rack/oauth2/server/token/extension/jwt.rb +37 -0
- data/lib/rack/oauth2/server/token/facebook_token.rb +27 -0
- data/lib/rack/oauth2/server/token/password.rb +27 -0
- data/lib/rack/oauth2/server/token/refresh_token.rb +26 -0
- data/lib/rack/oauth2/util.rb +58 -0
- data/rack-oauth2.gemspec +30 -0
- data/spec/helpers/time.rb +19 -0
- data/spec/helpers/webmock_helper.rb +41 -0
- data/spec/mock_response/blank +0 -0
- data/spec/mock_response/errors/invalid_request.json +4 -0
- data/spec/mock_response/resources/fake.txt +1 -0
- data/spec/mock_response/tokens/_Bearer.json +6 -0
- data/spec/mock_response/tokens/bearer.json +6 -0
- data/spec/mock_response/tokens/legacy.json +5 -0
- data/spec/mock_response/tokens/legacy.txt +1 -0
- data/spec/mock_response/tokens/legacy_without_expires_in.txt +1 -0
- data/spec/mock_response/tokens/mac.json +8 -0
- data/spec/mock_response/tokens/unknown.json +6 -0
- data/spec/rack/oauth2/access_token/authenticator_spec.rb +43 -0
- data/spec/rack/oauth2/access_token/bearer_spec.rb +18 -0
- data/spec/rack/oauth2/access_token/legacy_spec.rb +23 -0
- data/spec/rack/oauth2/access_token/mac/sha256_hex_verifier_spec.rb +28 -0
- data/spec/rack/oauth2/access_token/mac/signature_spec.rb +59 -0
- data/spec/rack/oauth2/access_token/mac/verifier_spec.rb +25 -0
- data/spec/rack/oauth2/access_token/mac_spec.rb +141 -0
- data/spec/rack/oauth2/access_token_spec.rb +69 -0
- data/spec/rack/oauth2/client/error_spec.rb +18 -0
- data/spec/rack/oauth2/client/grant/authorization_code_spec.rb +37 -0
- data/spec/rack/oauth2/client/grant/client_credentials_spec.rb +7 -0
- data/spec/rack/oauth2/client/grant/password_spec.rb +33 -0
- data/spec/rack/oauth2/client/grant/refresh_token_spec.rb +21 -0
- data/spec/rack/oauth2/client_spec.rb +287 -0
- data/spec/rack/oauth2/debugger/request_filter_spec.rb +33 -0
- data/spec/rack/oauth2/oauth2_spec.rb +74 -0
- data/spec/rack/oauth2/server/abstract/error_spec.rb +59 -0
- data/spec/rack/oauth2/server/authorize/code_spec.rb +57 -0
- data/spec/rack/oauth2/server/authorize/error_spec.rb +103 -0
- data/spec/rack/oauth2/server/authorize/extensions/code_and_token_spec.rb +60 -0
- data/spec/rack/oauth2/server/authorize/token_spec.rb +73 -0
- data/spec/rack/oauth2/server/authorize_spec.rb +214 -0
- data/spec/rack/oauth2/server/resource/bearer/error_spec.rb +52 -0
- data/spec/rack/oauth2/server/resource/bearer_spec.rb +123 -0
- data/spec/rack/oauth2/server/resource/error_spec.rb +147 -0
- data/spec/rack/oauth2/server/resource/mac/error_spec.rb +52 -0
- data/spec/rack/oauth2/server/resource/mac_spec.rb +119 -0
- data/spec/rack/oauth2/server/resource_spec.rb +23 -0
- data/spec/rack/oauth2/server/token/authorization_code_spec.rb +43 -0
- data/spec/rack/oauth2/server/token/client_credentials_spec.rb +23 -0
- data/spec/rack/oauth2/server/token/error_spec.rb +77 -0
- data/spec/rack/oauth2/server/token/password_spec.rb +37 -0
- data/spec/rack/oauth2/server/token/refresh_token_spec.rb +34 -0
- data/spec/rack/oauth2/server/token_spec.rb +134 -0
- data/spec/rack/oauth2/util_spec.rb +97 -0
- data/spec/spec_helper.rb +14 -0
- metadata +326 -0
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Rack::OAuth2::AccessToken::MAC::Verifier do
         | 
| 4 | 
            +
              let(:verifier) { Rack::OAuth2::AccessToken::MAC::Verifier.new(:algorithm => algorithm) }
         | 
| 5 | 
            +
              subject { verifier }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              context 'when "hmac-sha-1" is specified' do
         | 
| 8 | 
            +
                let(:algorithm) { 'hmac-sha-1' }
         | 
| 9 | 
            +
                its(:hash_generator) { should be_instance_of OpenSSL::Digest::SHA1 }
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              context 'when "hmac-sha-256" is specified' do
         | 
| 13 | 
            +
                let(:algorithm) { 'hmac-sha-256' }
         | 
| 14 | 
            +
                its(:hash_generator) { should be_instance_of OpenSSL::Digest::SHA256 }
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              context 'otherwise' do
         | 
| 18 | 
            +
                let(:algorithm) { 'invalid' }
         | 
| 19 | 
            +
                it do
         | 
| 20 | 
            +
                  expect { verifier.send(:hash_generator) }.to raise_error(StandardError, 'Unsupported Algorithm')
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              
         | 
| 25 | 
            +
            end
         | 
| @@ -0,0 +1,141 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Rack::OAuth2::AccessToken::MAC do
         | 
| 4 | 
            +
              let(:ts) { 1305820234 }
         | 
| 5 | 
            +
              let :token do
         | 
| 6 | 
            +
                Rack::OAuth2::AccessToken::MAC.new(
         | 
| 7 | 
            +
                  :access_token => 'access_token',
         | 
| 8 | 
            +
                  :mac_key => 'secret',
         | 
| 9 | 
            +
                  :mac_algorithm => 'hmac-sha-256',
         | 
| 10 | 
            +
                  :ts => ts
         | 
| 11 | 
            +
                )
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
              let :token_with_ext_verifier do
         | 
| 14 | 
            +
                Rack::OAuth2::AccessToken::MAC.new(
         | 
| 15 | 
            +
                  :access_token => 'access_token',
         | 
| 16 | 
            +
                  :mac_key => 'secret',
         | 
| 17 | 
            +
                  :mac_algorithm => 'hmac-sha-256',
         | 
| 18 | 
            +
                  :ts => ts,
         | 
| 19 | 
            +
                  :ext_verifier => Rack::OAuth2::AccessToken::MAC::Sha256HexVerifier
         | 
| 20 | 
            +
                )
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
              let(:nonce) { '1000:51e74de734c05613f37520872e68db5f' }
         | 
| 23 | 
            +
              let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
         | 
| 24 | 
            +
              subject { token }
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              its(:mac_key)    { should == 'secret' }
         | 
| 27 | 
            +
              its(:mac_algorithm) { should == 'hmac-sha-256' }
         | 
| 28 | 
            +
              its(:token_response) do
         | 
| 29 | 
            +
                should == {
         | 
| 30 | 
            +
                  :access_token => 'access_token',
         | 
| 31 | 
            +
                  :refresh_token => nil,
         | 
| 32 | 
            +
                  :token_type => :mac,
         | 
| 33 | 
            +
                  :expires_in => nil,
         | 
| 34 | 
            +
                  :scope => '',
         | 
| 35 | 
            +
                  :mac_key => 'secret',
         | 
| 36 | 
            +
                  :mac_algorithm => 'hmac-sha-256'
         | 
| 37 | 
            +
                }
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
              its(:generate_nonce) { should be_a String }
         | 
| 40 | 
            +
             | 
| 41 | 
            +
              describe 'verify!' do
         | 
| 42 | 
            +
                let(:request) { Rack::OAuth2::Server::Resource::MAC::Request.new(env) }
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                context 'when no ext_verifier is given' do
         | 
| 45 | 
            +
                  let(:env) do
         | 
| 46 | 
            +
                    Rack::MockRequest.env_for(
         | 
| 47 | 
            +
                      '/protected_resources',
         | 
| 48 | 
            +
                      'HTTP_AUTHORIZATION' => %{MAC id="access_token", nonce="#{nonce}", ts="#{ts}" mac="#{signature}"}
         | 
| 49 | 
            +
                    )
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  context 'when signature is valid' do
         | 
| 53 | 
            +
                    let(:signature) { 'BgooS/voPOZWLwoVfx4+zbC3xAVKW3jtjhKYOfIGZOA=' }
         | 
| 54 | 
            +
                    it do
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                      token.verify!(request.setup!).should == :verified
         | 
| 57 | 
            +
                    end
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  context 'otherwise' do
         | 
| 61 | 
            +
                    let(:signature) { 'invalid' }
         | 
| 62 | 
            +
                    it do
         | 
| 63 | 
            +
                      expect { token.verify!(request.setup!) }.to raise_error(
         | 
| 64 | 
            +
                        Rack::OAuth2::Server::Resource::MAC::Unauthorized,
         | 
| 65 | 
            +
                        'invalid_token :: Signature Invalid'
         | 
| 66 | 
            +
                      )
         | 
| 67 | 
            +
                    end
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                context 'when ext_verifier is given' do
         | 
| 72 | 
            +
                  let(:env) do
         | 
| 73 | 
            +
                    Rack::MockRequest.env_for(
         | 
| 74 | 
            +
                      '/protected_resources',
         | 
| 75 | 
            +
                      :method => :POST,
         | 
| 76 | 
            +
                      :params => {
         | 
| 77 | 
            +
                        :key1 => 'value1'
         | 
| 78 | 
            +
                      },
         | 
| 79 | 
            +
                      'HTTP_AUTHORIZATION' => %{MAC id="access_token", nonce="#{nonce}", ts="#{ts}", mac="#{signature}", ext="#{ext}"}
         | 
| 80 | 
            +
                    )
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
                  let(:signature) { 'invalid' }
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  context 'when ext is invalid' do
         | 
| 85 | 
            +
                    let(:ext) { 'invalid' }
         | 
| 86 | 
            +
                    it do
         | 
| 87 | 
            +
                      expect { token_with_ext_verifier.verify!(request.setup!) }.to raise_error(
         | 
| 88 | 
            +
                        Rack::OAuth2::Server::Resource::MAC::Unauthorized,
         | 
| 89 | 
            +
                        'invalid_token :: Sha256HexVerifier Invalid'
         | 
| 90 | 
            +
                      )
         | 
| 91 | 
            +
                    end
         | 
| 92 | 
            +
                  end
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                  context 'when ext is valid' do
         | 
| 95 | 
            +
                    let(:ext) { '4cfcd46c59f54b5ea6a5f9b05c28b52fef2864747194b5fdfc3d59c0057bf35a' }
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                    context 'when signature is valid' do
         | 
| 98 | 
            +
                      let(:signature) { 'dZYR54n+Lym5qCRRmDqmRZ71rG+bkjSWmqrOv8OjYHk=' }
         | 
| 99 | 
            +
                      it do
         | 
| 100 | 
            +
                        Time.fix(Time.at(1302361200)) do
         | 
| 101 | 
            +
                          token_with_ext_verifier.verify!(request.setup!).should == :verified
         | 
| 102 | 
            +
                        end
         | 
| 103 | 
            +
                      end
         | 
| 104 | 
            +
                    end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                    context 'otherwise' do
         | 
| 107 | 
            +
                      it do
         | 
| 108 | 
            +
                        expect { token.verify!(request.setup!) }.to raise_error(
         | 
| 109 | 
            +
                          Rack::OAuth2::Server::Resource::MAC::Unauthorized,
         | 
| 110 | 
            +
                          'invalid_token :: Signature Invalid'
         | 
| 111 | 
            +
                        )
         | 
| 112 | 
            +
                      end
         | 
| 113 | 
            +
                    end
         | 
| 114 | 
            +
                  end
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
              end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
              describe '.authenticate' do
         | 
| 119 | 
            +
                let(:request) { HTTPClient.new.send(:create_request, :post, URI.parse(resource_endpoint), {}, {:hello => "world"}, {}) }
         | 
| 120 | 
            +
                context 'when no ext_verifier is given' do
         | 
| 121 | 
            +
                  let(:signature) { 'pOBaL6HRawe4tUPmcU4vJEj1f2GJqrbQOlCcdAYgI/s=' }
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                  it 'should set Authorization header' do
         | 
| 124 | 
            +
                    token.should_receive(:generate_nonce).and_return(nonce)
         | 
| 125 | 
            +
                    request.header.should_receive(:[]=).with('Authorization', "MAC id=\"access_token\", nonce=\"#{nonce}\", ts=\"#{ts.to_i}\", mac=\"#{signature}\"")
         | 
| 126 | 
            +
                    token.authenticate(request)
         | 
| 127 | 
            +
                  end
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                context 'when ext_verifier is given' do
         | 
| 131 | 
            +
                  let(:signature) { 'vgU0fj6rSpwUCAoCOrXlu8pZBR8a5Q5xIVlB4MCvJeM=' }
         | 
| 132 | 
            +
                  let(:ext) { '3d011e09502a84552a0f8ae112d024cc2c115597e3a577d5f49007902c221dc5' }
         | 
| 133 | 
            +
                  it 'should set Authorization header with ext_verifier' do
         | 
| 134 | 
            +
                    token_with_ext_verifier.should_receive(:generate_nonce).and_return(nonce)
         | 
| 135 | 
            +
                    request.header.should_receive(:[]=).with('Authorization', "MAC id=\"access_token\", nonce=\"#{nonce}\", ts=\"#{ts.to_i}\", mac=\"#{signature}\", ext=\"#{ext}\"")
         | 
| 136 | 
            +
                    token_with_ext_verifier.authenticate(request)
         | 
| 137 | 
            +
                  end
         | 
| 138 | 
            +
                end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
              end
         | 
| 141 | 
            +
            end
         | 
| @@ -0,0 +1,69 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Rack::OAuth2::AccessToken do
         | 
| 4 | 
            +
              let :token do
         | 
| 5 | 
            +
                Rack::OAuth2::AccessToken::Bearer.new(
         | 
| 6 | 
            +
                  :access_token => 'access_token',
         | 
| 7 | 
            +
                  :refresh_token => 'refresh_token',
         | 
| 8 | 
            +
                  :expires_in => 3600,
         | 
| 9 | 
            +
                  :scope => [:scope1, :scope2]
         | 
| 10 | 
            +
                )
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
              subject { token }
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              its(:access_token)  { should == 'access_token' }
         | 
| 15 | 
            +
              its(:refresh_token) { should == 'refresh_token' }
         | 
| 16 | 
            +
              its(:expires_in)    { should == 3600 }
         | 
| 17 | 
            +
              its(:scope)         { should == [:scope1, :scope2] }
         | 
| 18 | 
            +
              its(:token_response) do
         | 
| 19 | 
            +
                should == {
         | 
| 20 | 
            +
                  :token_type => :bearer,
         | 
| 21 | 
            +
                  :access_token => 'access_token',
         | 
| 22 | 
            +
                  :refresh_token => 'refresh_token',
         | 
| 23 | 
            +
                  :expires_in => 3600,
         | 
| 24 | 
            +
                  :scope => 'scope1 scope2'
         | 
| 25 | 
            +
                }
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              context 'when access_token is missing' do
         | 
| 29 | 
            +
                it do
         | 
| 30 | 
            +
                  expect do
         | 
| 31 | 
            +
                    Rack::OAuth2::AccessToken::Bearer.new(
         | 
| 32 | 
            +
                      :refresh_token => 'refresh_token',
         | 
| 33 | 
            +
                      :expires_in => 3600,
         | 
| 34 | 
            +
                      :scope => [:scope1, :scope2]
         | 
| 35 | 
            +
                    )
         | 
| 36 | 
            +
                  end.to raise_error AttrRequired::AttrMissing
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              context 'otherwise' do
         | 
| 41 | 
            +
                it do
         | 
| 42 | 
            +
                  expect do
         | 
| 43 | 
            +
                    Rack::OAuth2::AccessToken::Bearer.new(
         | 
| 44 | 
            +
                      :access_token => 'access_token'
         | 
| 45 | 
            +
                    )
         | 
| 46 | 
            +
                  end.not_to raise_error
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              let(:resource_endpoint) { 'https://server.example.com/resources/fake' }
         | 
| 51 | 
            +
              [:get, :delete, :post, :put].each do |method|
         | 
| 52 | 
            +
                describe method do
         | 
| 53 | 
            +
                  it 'should delegate to HTTPClient with Authenticator filter' do
         | 
| 54 | 
            +
                    token.httpclient.should_receive(method).with(resource_endpoint)
         | 
| 55 | 
            +
                    token.httpclient.request_filter.last.should be_a Rack::OAuth2::AccessToken::Authenticator
         | 
| 56 | 
            +
                    token.send method, resource_endpoint
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                context 'in debug mode' do
         | 
| 61 | 
            +
                  it do
         | 
| 62 | 
            +
                    Rack::OAuth2.debug do
         | 
| 63 | 
            +
                      token.httpclient.request_filter[-2].should be_a Rack::OAuth2::AccessToken::Authenticator
         | 
| 64 | 
            +
                      token.httpclient.request_filter.last.should be_a Rack::OAuth2::Debugger::RequestFilter
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            require 'spec_helper.rb'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Rack::OAuth2::Client::Error do
         | 
| 4 | 
            +
              let :error do
         | 
| 5 | 
            +
                {
         | 
| 6 | 
            +
                  :error => :invalid_request,
         | 
| 7 | 
            +
                  :error_description => 'Include invalid parameters',
         | 
| 8 | 
            +
                  :error_uri => 'http://server.example.com/error/invalid_request'
         | 
| 9 | 
            +
                }
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
              subject do
         | 
| 12 | 
            +
                Rack::OAuth2::Client::Error.new 400, error
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              its(:status)   { should == 400 }
         | 
| 16 | 
            +
              its(:message)  { should == error[:error_description] }
         | 
| 17 | 
            +
              its(:response) { should == error }
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            require 'spec_helper.rb'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Rack::OAuth2::Client::Grant::AuthorizationCode do
         | 
| 4 | 
            +
              let(:redirect_uri) { 'https://client.example.com/callback' }
         | 
| 5 | 
            +
              let(:grant) { Rack::OAuth2::Client::Grant::AuthorizationCode }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              context 'when code is given' do
         | 
| 8 | 
            +
                let :attributes do
         | 
| 9 | 
            +
                  {:code => 'code'}
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                context 'when redirect_uri is given' do
         | 
| 13 | 
            +
                  let :attributes do
         | 
| 14 | 
            +
                    {:code => 'code', :redirect_uri => redirect_uri}
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                  subject { grant.new attributes }
         | 
| 17 | 
            +
                  its(:redirect_uri) { should == redirect_uri }
         | 
| 18 | 
            +
                  its(:as_json) do
         | 
| 19 | 
            +
                    should == {:grant_type => :authorization_code, :code => 'code', :redirect_uri => redirect_uri}
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                context 'otherwise' do
         | 
| 24 | 
            +
                  subject { grant.new attributes }
         | 
| 25 | 
            +
                  its(:redirect_uri) { should be_nil }
         | 
| 26 | 
            +
                  its(:as_json) do
         | 
| 27 | 
            +
                    should == {:grant_type => :authorization_code, :code => 'code', :redirect_uri => nil}
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              context 'otherwise' do
         | 
| 33 | 
            +
                it do
         | 
| 34 | 
            +
                  expect { grant.new }.to raise_error AttrRequired::AttrMissing
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
            end
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            require 'spec_helper.rb'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Rack::OAuth2::Client::Grant::Password do
         | 
| 4 | 
            +
              let(:grant) { Rack::OAuth2::Client::Grant::Password }
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              context 'when username is given' do
         | 
| 7 | 
            +
                let :attributes do
         | 
| 8 | 
            +
                  {:username => 'username'}
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                context 'when password is given' do
         | 
| 12 | 
            +
                  let :attributes do
         | 
| 13 | 
            +
                    {:username => 'username', :password => 'password'}
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                  subject { grant.new attributes }
         | 
| 16 | 
            +
                  its(:as_json) do
         | 
| 17 | 
            +
                    should == {:grant_type => :password, :username => 'username', :password => 'password'}
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                context 'otherwise' do
         | 
| 22 | 
            +
                  it do
         | 
| 23 | 
            +
                    expect { grant.new attributes }.to raise_error AttrRequired::AttrMissing
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              context 'otherwise' do
         | 
| 29 | 
            +
                it do
         | 
| 30 | 
            +
                  expect { grant.new }.to raise_error AttrRequired::AttrMissing
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            require 'spec_helper.rb'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Rack::OAuth2::Client::Grant::RefreshToken do
         | 
| 4 | 
            +
              let(:grant) { Rack::OAuth2::Client::Grant::RefreshToken }
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              context 'when refresh_token is given' do
         | 
| 7 | 
            +
                let :attributes do
         | 
| 8 | 
            +
                  {:refresh_token => 'refresh_token'}
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
                subject { grant.new attributes }
         | 
| 11 | 
            +
                its(:as_json) do
         | 
| 12 | 
            +
                  should == {:grant_type => :refresh_token, :refresh_token => 'refresh_token'}
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              context 'otherwise' do
         | 
| 17 | 
            +
                it do
         | 
| 18 | 
            +
                  expect { grant.new }.to raise_error AttrRequired::AttrMissing
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
| @@ -0,0 +1,287 @@ | |
| 1 | 
            +
            require 'spec_helper.rb'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Rack::OAuth2::Client do
         | 
| 4 | 
            +
              let :client do
         | 
| 5 | 
            +
                Rack::OAuth2::Client.new(
         | 
| 6 | 
            +
                  :identifier => 'client_id',
         | 
| 7 | 
            +
                  :secret => 'client_secret',
         | 
| 8 | 
            +
                  :host => 'server.example.com',
         | 
| 9 | 
            +
                  :redirect_uri => 'https://client.example.com/callback'
         | 
| 10 | 
            +
                )
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
              subject { client }
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              its(:identifier) { should == 'client_id' }
         | 
| 15 | 
            +
              its(:secret)     { should == 'client_secret' }
         | 
| 16 | 
            +
              its(:authorization_endpoint) { should == '/oauth2/authorize' }
         | 
| 17 | 
            +
              its(:token_endpoint)         { should == '/oauth2/token' }
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              context 'when identifier is missing' do
         | 
| 20 | 
            +
                it do
         | 
| 21 | 
            +
                  expect { Rack::OAuth2::Client.new }.to raise_error AttrRequired::AttrMissing
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              describe '#authorization_uri' do
         | 
| 26 | 
            +
                subject { client.authorization_uri }
         | 
| 27 | 
            +
                it { should include 'https://server.example.com/oauth2/authorize' }
         | 
| 28 | 
            +
                it { should include 'client_id=client_id' }
         | 
| 29 | 
            +
                it { should include 'redirect_uri=https%3A%2F%2Fclient.example.com%2Fcallback' }
         | 
| 30 | 
            +
                it { should include 'response_type=code' }
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                context 'when endpoints are absolute URIs' do
         | 
| 33 | 
            +
                  before do
         | 
| 34 | 
            +
                    client.authorization_endpoint = 'https://server2.example.com/oauth/authorize'
         | 
| 35 | 
            +
                    client.token_endpoint = 'https://server2.example.com/oauth/token'
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
                  it { should include 'https://server2.example.com/oauth/authorize' }
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                context 'when scheme is specified' do
         | 
| 41 | 
            +
                  before { client.scheme = 'http' }
         | 
| 42 | 
            +
                  it { should include 'http://server.example.com/oauth2/authorize' }
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                context 'when response_type is token' do
         | 
| 46 | 
            +
                  subject { client.authorization_uri(:response_type => :token) }
         | 
| 47 | 
            +
                  it { should include 'response_type=token' }
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                context 'when response_type is an Array' do
         | 
| 51 | 
            +
                  subject { client.authorization_uri(:response_type => [:token, :code]) }
         | 
| 52 | 
            +
                  it { should include 'response_type=token+code' }
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                context 'when scope is given' do
         | 
| 56 | 
            +
                  subject { client.authorization_uri(:scope => [:scope1, :scope2]) }
         | 
| 57 | 
            +
                  it { should include 'scope=scope1+scope2' }
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
              describe '#authorization_code=' do
         | 
| 62 | 
            +
                before  { client.authorization_code = 'code' }
         | 
| 63 | 
            +
                subject { client.instance_variable_get('@grant') }
         | 
| 64 | 
            +
                it { should be_instance_of Rack::OAuth2::Client::Grant::AuthorizationCode }
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              describe '#resource_owner_credentials=' do
         | 
| 68 | 
            +
                before  { client.resource_owner_credentials = 'username', 'password' }
         | 
| 69 | 
            +
                subject { client.instance_variable_get('@grant') }
         | 
| 70 | 
            +
                it { should be_instance_of Rack::OAuth2::Client::Grant::Password }
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              describe '#refresh_token=' do
         | 
| 74 | 
            +
                before  { client.refresh_token = 'refresh_token' }
         | 
| 75 | 
            +
                subject { client.instance_variable_get('@grant') }
         | 
| 76 | 
            +
                it { should be_instance_of Rack::OAuth2::Client::Grant::RefreshToken }
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
              describe '#access_token!' do
         | 
| 80 | 
            +
                subject { client.access_token! }
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                describe 'client authentication method' do
         | 
| 83 | 
            +
                  before do
         | 
| 84 | 
            +
                    client.authorization_code = 'code'
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  it 'should be Basic auth as default' do
         | 
| 88 | 
            +
                    mock_response(
         | 
| 89 | 
            +
                      :post,
         | 
| 90 | 
            +
                      'https://server.example.com/oauth2/token',
         | 
| 91 | 
            +
                      'tokens/bearer.json',
         | 
| 92 | 
            +
                      :request_header => {
         | 
| 93 | 
            +
                        'Authorization' => 'Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ='
         | 
| 94 | 
            +
                      }
         | 
| 95 | 
            +
                    )
         | 
| 96 | 
            +
                    client.access_token!
         | 
| 97 | 
            +
                  end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                  context 'when other auth method specified' do
         | 
| 100 | 
            +
                    it do
         | 
| 101 | 
            +
                      mock_response(
         | 
| 102 | 
            +
                        :post,
         | 
| 103 | 
            +
                        'https://server.example.com/oauth2/token',
         | 
| 104 | 
            +
                        'tokens/bearer.json',
         | 
| 105 | 
            +
                        :params => {
         | 
| 106 | 
            +
                          :client_id => 'client_id',
         | 
| 107 | 
            +
                          :client_secret => 'client_secret',
         | 
| 108 | 
            +
                          :code => 'code',
         | 
| 109 | 
            +
                          :grant_type => 'authorization_code',
         | 
| 110 | 
            +
                          :redirect_uri => 'https://client.example.com/callback'
         | 
| 111 | 
            +
                        }
         | 
| 112 | 
            +
                      )
         | 
| 113 | 
            +
                      client.access_token! :client_auth_body
         | 
| 114 | 
            +
                    end
         | 
| 115 | 
            +
                  end
         | 
| 116 | 
            +
                end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                describe 'scopes' do
         | 
| 119 | 
            +
                  context 'when scope option given' do
         | 
| 120 | 
            +
                    it 'should specify given scope' do
         | 
| 121 | 
            +
                      mock_response(
         | 
| 122 | 
            +
                        :post,
         | 
| 123 | 
            +
                        'https://server.example.com/oauth2/token',
         | 
| 124 | 
            +
                        'tokens/bearer.json',
         | 
| 125 | 
            +
                        :params => {
         | 
| 126 | 
            +
                          :grant_type => 'client_credentials',
         | 
| 127 | 
            +
                          :scope => 'a b'
         | 
| 128 | 
            +
                        }
         | 
| 129 | 
            +
                      )
         | 
| 130 | 
            +
                      client.access_token! :scope => [:a, :b]
         | 
| 131 | 
            +
                    end
         | 
| 132 | 
            +
                  end
         | 
| 133 | 
            +
                end
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                context 'when bearer token is given' do
         | 
| 136 | 
            +
                  before  do
         | 
| 137 | 
            +
                    client.authorization_code = 'code'
         | 
| 138 | 
            +
                    mock_response(
         | 
| 139 | 
            +
                      :post,
         | 
| 140 | 
            +
                      'https://server.example.com/oauth2/token',
         | 
| 141 | 
            +
                      'tokens/bearer.json'
         | 
| 142 | 
            +
                    )
         | 
| 143 | 
            +
                  end
         | 
| 144 | 
            +
                  it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
         | 
| 145 | 
            +
                  its(:token_type) { should == :bearer }
         | 
| 146 | 
            +
                  its(:access_token) { should == 'access_token' }
         | 
| 147 | 
            +
                  its(:refresh_token) { should == 'refresh_token' }
         | 
| 148 | 
            +
                  its(:expires_in) { should == 3600 }
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                  context 'when token type is "Bearer", not "bearer"' do
         | 
| 151 | 
            +
                    before  do
         | 
| 152 | 
            +
                      client.authorization_code = 'code'
         | 
| 153 | 
            +
                      mock_response(
         | 
| 154 | 
            +
                        :post,
         | 
| 155 | 
            +
                        'https://server.example.com/oauth2/token',
         | 
| 156 | 
            +
                        'tokens/_Bearer.json'
         | 
| 157 | 
            +
                      )
         | 
| 158 | 
            +
                    end
         | 
| 159 | 
            +
                    it { should be_instance_of Rack::OAuth2::AccessToken::Bearer }
         | 
| 160 | 
            +
                    its(:token_type) { should == :bearer }
         | 
| 161 | 
            +
                  end
         | 
| 162 | 
            +
                end
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                context 'when mac token is given' do
         | 
| 165 | 
            +
                  before  do
         | 
| 166 | 
            +
                    client.authorization_code = 'code'
         | 
| 167 | 
            +
                    mock_response(
         | 
| 168 | 
            +
                      :post,
         | 
| 169 | 
            +
                      'https://server.example.com/oauth2/token',
         | 
| 170 | 
            +
                      'tokens/mac.json'
         | 
| 171 | 
            +
                    )
         | 
| 172 | 
            +
                  end
         | 
| 173 | 
            +
                  it { should be_instance_of Rack::OAuth2::AccessToken::MAC }
         | 
| 174 | 
            +
                  its(:token_type) { should == :mac }
         | 
| 175 | 
            +
                  its(:access_token) { should == 'access_token' }
         | 
| 176 | 
            +
                  its(:refresh_token) { should == 'refresh_token' }
         | 
| 177 | 
            +
                  its(:expires_in) { should == 3600 }
         | 
| 178 | 
            +
                end
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                context 'when no-type token is given (JSON)' do
         | 
| 181 | 
            +
                  before  do
         | 
| 182 | 
            +
                    client.authorization_code = 'code'
         | 
| 183 | 
            +
                    mock_response(
         | 
| 184 | 
            +
                      :post,
         | 
| 185 | 
            +
                      'https://server.example.com/oauth2/token',
         | 
| 186 | 
            +
                      'tokens/legacy.json'
         | 
| 187 | 
            +
                    )
         | 
| 188 | 
            +
                  end
         | 
| 189 | 
            +
                  it { should be_instance_of Rack::OAuth2::AccessToken::Legacy }
         | 
| 190 | 
            +
                  its(:token_type) { should == :legacy }
         | 
| 191 | 
            +
                  its(:access_token) { should == 'access_token' }
         | 
| 192 | 
            +
                  its(:refresh_token) { should == 'refresh_token' }
         | 
| 193 | 
            +
                  its(:expires_in) { should == 3600 }
         | 
| 194 | 
            +
                end
         | 
| 195 | 
            +
             | 
| 196 | 
            +
                context 'when no-type token is given (key-value)' do
         | 
| 197 | 
            +
                  before do
         | 
| 198 | 
            +
                    mock_response(
         | 
| 199 | 
            +
                      :post,
         | 
| 200 | 
            +
                      'https://server.example.com/oauth2/token',
         | 
| 201 | 
            +
                      'tokens/legacy.txt'
         | 
| 202 | 
            +
                    )
         | 
| 203 | 
            +
                  end
         | 
| 204 | 
            +
                  it { should be_instance_of Rack::OAuth2::AccessToken::Legacy }
         | 
| 205 | 
            +
                  its(:token_type) { should == :legacy }
         | 
| 206 | 
            +
                  its(:access_token) { should == 'access_token' }
         | 
| 207 | 
            +
                  its(:expires_in) { should == 3600 }
         | 
| 208 | 
            +
             | 
| 209 | 
            +
                  context 'when expires_in is not given' do
         | 
| 210 | 
            +
                    before do
         | 
| 211 | 
            +
                      mock_response(
         | 
| 212 | 
            +
                        :post,
         | 
| 213 | 
            +
                        'https://server.example.com/oauth2/token',
         | 
| 214 | 
            +
                        'tokens/legacy_without_expires_in.txt'
         | 
| 215 | 
            +
                      )
         | 
| 216 | 
            +
                    end
         | 
| 217 | 
            +
                    its(:expires_in) { should be_nil }
         | 
| 218 | 
            +
                  end
         | 
| 219 | 
            +
                end
         | 
| 220 | 
            +
             | 
| 221 | 
            +
                context 'when unknown-type token is given' do
         | 
| 222 | 
            +
                  before  do
         | 
| 223 | 
            +
                    client.authorization_code = 'code'
         | 
| 224 | 
            +
                    mock_response(
         | 
| 225 | 
            +
                      :post,
         | 
| 226 | 
            +
                      'https://server.example.com/oauth2/token',
         | 
| 227 | 
            +
                      'tokens/unknown.json'
         | 
| 228 | 
            +
                    )
         | 
| 229 | 
            +
                  end
         | 
| 230 | 
            +
                  it do
         | 
| 231 | 
            +
                    expect { client.access_token! }.to raise_error(StandardError, 'Unknown Token Type')
         | 
| 232 | 
            +
                  end
         | 
| 233 | 
            +
                end
         | 
| 234 | 
            +
             | 
| 235 | 
            +
                context 'when error response is given' do
         | 
| 236 | 
            +
                  before do
         | 
| 237 | 
            +
                    mock_response(
         | 
| 238 | 
            +
                      :post,
         | 
| 239 | 
            +
                      'https://server.example.com/oauth2/token',
         | 
| 240 | 
            +
                      'errors/invalid_request.json',
         | 
| 241 | 
            +
                      :status => 400
         | 
| 242 | 
            +
                    )
         | 
| 243 | 
            +
                  end
         | 
| 244 | 
            +
                  it do
         | 
| 245 | 
            +
                    expect { client.access_token! }.to raise_error Rack::OAuth2::Client::Error
         | 
| 246 | 
            +
                  end
         | 
| 247 | 
            +
                end
         | 
| 248 | 
            +
             | 
| 249 | 
            +
                context 'when no body given' do
         | 
| 250 | 
            +
                  context 'when error given' do
         | 
| 251 | 
            +
                    before do
         | 
| 252 | 
            +
                      mock_response(
         | 
| 253 | 
            +
                        :post,
         | 
| 254 | 
            +
                        'https://server.example.com/oauth2/token',
         | 
| 255 | 
            +
                        'blank',
         | 
| 256 | 
            +
                        :status => 400
         | 
| 257 | 
            +
                      )
         | 
| 258 | 
            +
                    end
         | 
| 259 | 
            +
                    it do
         | 
| 260 | 
            +
                      expect { client.access_token! }.to raise_error Rack::OAuth2::Client::Error
         | 
| 261 | 
            +
                    end
         | 
| 262 | 
            +
                  end
         | 
| 263 | 
            +
                end
         | 
| 264 | 
            +
              end
         | 
| 265 | 
            +
             | 
| 266 | 
            +
              context 'when no host info' do
         | 
| 267 | 
            +
                let :client do
         | 
| 268 | 
            +
                  Rack::OAuth2::Client.new(
         | 
| 269 | 
            +
                    :identifier => 'client_id',
         | 
| 270 | 
            +
                    :secret => 'client_secret',
         | 
| 271 | 
            +
                    :redirect_uri => 'https://client.example.com/callback'
         | 
| 272 | 
            +
                  )
         | 
| 273 | 
            +
                end
         | 
| 274 | 
            +
             | 
| 275 | 
            +
                describe '#authorization_uri' do
         | 
| 276 | 
            +
                  it do
         | 
| 277 | 
            +
                    expect { client.authorization_uri }.to raise_error 'No Host Info'
         | 
| 278 | 
            +
                  end
         | 
| 279 | 
            +
                end
         | 
| 280 | 
            +
             | 
| 281 | 
            +
                describe '#access_token!' do
         | 
| 282 | 
            +
                  it do
         | 
| 283 | 
            +
                    expect { client.access_token! }.to raise_error 'No Host Info'
         | 
| 284 | 
            +
                  end
         | 
| 285 | 
            +
                end
         | 
| 286 | 
            +
              end
         | 
| 287 | 
            +
            end
         |