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,214 @@ | |
| 1 | 
            +
            require 'spec_helper.rb'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Rack::OAuth2::Server::Authorize do
         | 
| 4 | 
            +
              let(:app)          { Rack::OAuth2::Server::Authorize.new }
         | 
| 5 | 
            +
              let(:request)      { Rack::MockRequest.new app }
         | 
| 6 | 
            +
              let(:redirect_uri) { 'http://client.example.com/callback' }
         | 
| 7 | 
            +
              let(:bad_request)  { Rack::OAuth2::Server::Authorize::BadRequest }
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              context 'when response_type is missing' do
         | 
| 10 | 
            +
                it do
         | 
| 11 | 
            +
                  expect { request.get "/?client_id=client&redirect_uri=#{redirect_uri}" }.to raise_error bad_request
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              context 'when redirect_uri is missing' do
         | 
| 16 | 
            +
                it do
         | 
| 17 | 
            +
                  expect { request.get "/?response_type=code&client_id=client" }.not_to raise_error
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              context 'when client_id is missing' do
         | 
| 22 | 
            +
                it do
         | 
| 23 | 
            +
                  expect { request.get "/?response_type=code&redirect_uri=#{redirect_uri}" }.to raise_error bad_request
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              context 'when unknown response_type is given' do
         | 
| 28 | 
            +
                it do
         | 
| 29 | 
            +
                  expect { request.get "/?response_type=unknown&client_id=client&redirect_uri=#{redirect_uri}" }.to raise_error bad_request
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              context 'when all required parameters are valid' do
         | 
| 34 | 
            +
                [:code, :token].each do |request_type|
         | 
| 35 | 
            +
                  context "when response_type = :#{request_type}" do
         | 
| 36 | 
            +
                    subject { request.get "/?response_type=#{request_type}&client_id=client&redirect_uri=#{redirect_uri}" }
         | 
| 37 | 
            +
                    its(:status) { should == 200 }
         | 
| 38 | 
            +
                  end
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
              end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
              describe Rack::OAuth2::Server::Authorize::Request do
         | 
| 43 | 
            +
                let(:env)     { Rack::MockRequest.env_for("/authorize?client_id=client&redirect_uri=#{redirect_uri}") }
         | 
| 44 | 
            +
                let(:request) { Rack::OAuth2::Server::Authorize::Request.new env }
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                describe '#varified_redirect_uri' do
         | 
| 47 | 
            +
                  context 'when an Array of pre-registered URIs are given' do
         | 
| 48 | 
            +
                    context 'when given redirect_uri is valid against one of them' do
         | 
| 49 | 
            +
                      let :pre_registered do
         | 
| 50 | 
            +
                        [
         | 
| 51 | 
            +
                          redirect_uri,
         | 
| 52 | 
            +
                          'http://ja.client.example.com/callback',
         | 
| 53 | 
            +
                          'http://en.client.example.com/callback'
         | 
| 54 | 
            +
                        ]
         | 
| 55 | 
            +
                      end
         | 
| 56 | 
            +
                      it 'should be valid' do
         | 
| 57 | 
            +
                        request.verify_redirect_uri!(pre_registered).should == redirect_uri
         | 
| 58 | 
            +
                      end
         | 
| 59 | 
            +
                    end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                    context 'otherwise' do
         | 
| 62 | 
            +
                      let :pre_registered do
         | 
| 63 | 
            +
                        [
         | 
| 64 | 
            +
                          'http://ja.client.example.com/callback',
         | 
| 65 | 
            +
                          'http://en.client.example.com/callback'
         | 
| 66 | 
            +
                        ]
         | 
| 67 | 
            +
                      end
         | 
| 68 | 
            +
                      it do
         | 
| 69 | 
            +
                        expect do
         | 
| 70 | 
            +
                          request.verify_redirect_uri!(pre_registered)
         | 
| 71 | 
            +
                        end.to raise_error bad_request
         | 
| 72 | 
            +
                      end
         | 
| 73 | 
            +
                    end
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  context 'when exact mathed redirect_uri is given' do
         | 
| 77 | 
            +
                    let(:pre_registered) { redirect_uri }
         | 
| 78 | 
            +
                    it 'should be valid' do
         | 
| 79 | 
            +
                      request.verify_redirect_uri!(pre_registered).should == redirect_uri
         | 
| 80 | 
            +
                    end
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  context 'when partially mathed redirect_uri is given' do
         | 
| 84 | 
            +
                    let(:pre_registered) { 'http://client.example.com' }
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                    context 'when partial matching allowed' do
         | 
| 87 | 
            +
                      it 'should be valid' do
         | 
| 88 | 
            +
                        request.verify_redirect_uri!(pre_registered, :allow_partial_match).should == redirect_uri
         | 
| 89 | 
            +
                      end
         | 
| 90 | 
            +
                    end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                    context 'otherwise' do
         | 
| 93 | 
            +
                      it do
         | 
| 94 | 
            +
                        expect do
         | 
| 95 | 
            +
                          request.verify_redirect_uri!(pre_registered)
         | 
| 96 | 
            +
                        end.to raise_error bad_request
         | 
| 97 | 
            +
                      end
         | 
| 98 | 
            +
                    end
         | 
| 99 | 
            +
                  end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
                  context 'when invalid redirect_uri is given' do
         | 
| 102 | 
            +
                    let(:pre_registered) { 'http://client2.example.com' }
         | 
| 103 | 
            +
                    it do
         | 
| 104 | 
            +
                      expect do
         | 
| 105 | 
            +
                        request.verify_redirect_uri!(pre_registered)
         | 
| 106 | 
            +
                      end.to raise_error bad_request
         | 
| 107 | 
            +
                    end
         | 
| 108 | 
            +
                  end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                  context 'when redirect_uri is missing' do
         | 
| 111 | 
            +
                    let(:env) { Rack::MockRequest.env_for("/authorize?client_id=client") }
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                    context 'when pre-registered redirect_uri is a String' do
         | 
| 114 | 
            +
                      let(:pre_registered) { redirect_uri }
         | 
| 115 | 
            +
                      it 'should use pre-registered redirect_uri' do
         | 
| 116 | 
            +
                        request.verify_redirect_uri!(pre_registered).should == pre_registered
         | 
| 117 | 
            +
                      end
         | 
| 118 | 
            +
                    end
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                    context 'when pre-registered redirect_uri is an Array' do
         | 
| 121 | 
            +
                      context 'when only 1' do
         | 
| 122 | 
            +
                        let(:pre_registered) { [redirect_uri] }
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                        context 'when partial match allowed' do
         | 
| 125 | 
            +
                          it do
         | 
| 126 | 
            +
                            expect do
         | 
| 127 | 
            +
                              request.verify_redirect_uri!(pre_registered, :allow_partial_match)
         | 
| 128 | 
            +
                            end.to raise_error bad_request
         | 
| 129 | 
            +
                          end
         | 
| 130 | 
            +
                        end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
                        context 'otherwise' do
         | 
| 133 | 
            +
                          it 'should use pre-registered redirect_uri' do
         | 
| 134 | 
            +
                            request.verify_redirect_uri!(pre_registered).should == pre_registered.first
         | 
| 135 | 
            +
                          end
         | 
| 136 | 
            +
                        end
         | 
| 137 | 
            +
                      end
         | 
| 138 | 
            +
             | 
| 139 | 
            +
                      context 'when more than 2' do
         | 
| 140 | 
            +
                        let(:pre_registered) { [redirect_uri, 'http://client.example.com/callback2'] }
         | 
| 141 | 
            +
                        it do
         | 
| 142 | 
            +
                          expect do
         | 
| 143 | 
            +
                            request.verify_redirect_uri!(pre_registered)
         | 
| 144 | 
            +
                          end.to raise_error bad_request
         | 
| 145 | 
            +
                        end
         | 
| 146 | 
            +
                      end
         | 
| 147 | 
            +
                    end
         | 
| 148 | 
            +
                  end
         | 
| 149 | 
            +
                end
         | 
| 150 | 
            +
              end
         | 
| 151 | 
            +
             | 
| 152 | 
            +
              describe 'extensibility' do
         | 
| 153 | 
            +
                before do
         | 
| 154 | 
            +
                  require 'rack/oauth2/server/authorize/extension/code_and_token'
         | 
| 155 | 
            +
                end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                let(:env) do
         | 
| 158 | 
            +
                  Rack::MockRequest.env_for("/authorize?response_type=#{response_type}&client_id=client")
         | 
| 159 | 
            +
                end
         | 
| 160 | 
            +
                let(:request) { Rack::OAuth2::Server::Authorize::Request.new env }
         | 
| 161 | 
            +
                its(:extensions) { should == [Rack::OAuth2::Server::Authorize::Extension::CodeAndToken] }
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                describe 'code token' do
         | 
| 164 | 
            +
                  let(:response_type) { 'code%20token' }
         | 
| 165 | 
            +
                  it do
         | 
| 166 | 
            +
                    app.send(
         | 
| 167 | 
            +
                      :response_type_for, request
         | 
| 168 | 
            +
                    ).should == Rack::OAuth2::Server::Authorize::Extension::CodeAndToken
         | 
| 169 | 
            +
                  end
         | 
| 170 | 
            +
                end
         | 
| 171 | 
            +
             | 
| 172 | 
            +
                describe 'token code' do
         | 
| 173 | 
            +
                  let(:response_type) { 'token%20code' }
         | 
| 174 | 
            +
                  it do
         | 
| 175 | 
            +
                    app.send(
         | 
| 176 | 
            +
                      :response_type_for, request
         | 
| 177 | 
            +
                    ).should == Rack::OAuth2::Server::Authorize::Extension::CodeAndToken
         | 
| 178 | 
            +
                  end
         | 
| 179 | 
            +
                end
         | 
| 180 | 
            +
             | 
| 181 | 
            +
                describe 'token code id_token' do
         | 
| 182 | 
            +
                  let(:response_type) { 'token%20code%20id_token' }
         | 
| 183 | 
            +
                  it do
         | 
| 184 | 
            +
                    expect do
         | 
| 185 | 
            +
                      app.send(:response_type_for, request)
         | 
| 186 | 
            +
                    end.to raise_error bad_request
         | 
| 187 | 
            +
                  end
         | 
| 188 | 
            +
                end
         | 
| 189 | 
            +
             | 
| 190 | 
            +
                describe 'id_token' do
         | 
| 191 | 
            +
                  before do
         | 
| 192 | 
            +
                    class Rack::OAuth2::Server::Authorize::Extension::IdToken < Rack::OAuth2::Server::Abstract::Handler
         | 
| 193 | 
            +
                      def self.response_type_for?(response_type)
         | 
| 194 | 
            +
                        response_type == 'id_token'
         | 
| 195 | 
            +
                      end
         | 
| 196 | 
            +
                    end
         | 
| 197 | 
            +
                  end
         | 
| 198 | 
            +
             | 
| 199 | 
            +
                  its(:extensions) do
         | 
| 200 | 
            +
                    should == [
         | 
| 201 | 
            +
                      Rack::OAuth2::Server::Authorize::Extension::CodeAndToken,
         | 
| 202 | 
            +
                      Rack::OAuth2::Server::Authorize::Extension::IdToken
         | 
| 203 | 
            +
                    ]
         | 
| 204 | 
            +
                  end
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                  let(:response_type) { 'id_token' }
         | 
| 207 | 
            +
                  it do
         | 
| 208 | 
            +
                    app.send(
         | 
| 209 | 
            +
                      :response_type_for, request
         | 
| 210 | 
            +
                    ).should == Rack::OAuth2::Server::Authorize::Extension::IdToken
         | 
| 211 | 
            +
                  end
         | 
| 212 | 
            +
                end
         | 
| 213 | 
            +
              end
         | 
| 214 | 
            +
            end
         | 
| @@ -0,0 +1,52 @@ | |
| 1 | 
            +
            require 'spec_helper.rb'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Rack::OAuth2::Server::Resource::Bearer::Unauthorized do
         | 
| 4 | 
            +
              let(:error) { Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new(:invalid_token) }
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              it { should be_a Rack::OAuth2::Server::Resource::Unauthorized }
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              describe '#scheme' do
         | 
| 9 | 
            +
                subject { error }
         | 
| 10 | 
            +
                its(:scheme) { should == :Bearer }
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              describe '#finish' do
         | 
| 14 | 
            +
                it 'should use Bearer scheme' do
         | 
| 15 | 
            +
                  status, header, response = error.finish
         | 
| 16 | 
            +
                  header['WWW-Authenticate'].should include 'Bearer'
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            describe Rack::OAuth2::Server::Resource::Bearer::ErrorMethods do
         | 
| 22 | 
            +
              let(:unauthorized)        { Rack::OAuth2::Server::Resource::Bearer::Unauthorized }
         | 
| 23 | 
            +
              let(:redirect_uri)        { 'http://client.example.com/callback' }
         | 
| 24 | 
            +
              let(:default_description) { Rack::OAuth2::Server::Resource::ErrorMethods::DEFAULT_DESCRIPTION }
         | 
| 25 | 
            +
              let(:env)                 { Rack::MockRequest.env_for("/authorize?client_id=client_id") }
         | 
| 26 | 
            +
              let(:request)             { Rack::OAuth2::Server::Resource::Bearer::Request.new env }
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              describe 'unauthorized!' do
         | 
| 29 | 
            +
                it do
         | 
| 30 | 
            +
                  expect { request.unauthorized! :invalid_client }.to raise_error unauthorized
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              Rack::OAuth2::Server::Resource::Bearer::ErrorMethods::DEFAULT_DESCRIPTION.keys.each do |error_code|
         | 
| 35 | 
            +
                method = "#{error_code}!"
         | 
| 36 | 
            +
                case error_code
         | 
| 37 | 
            +
                when :invalid_request
         | 
| 38 | 
            +
                  # ignore
         | 
| 39 | 
            +
                when :insufficient_scope
         | 
| 40 | 
            +
                  # ignore
         | 
| 41 | 
            +
                else
         | 
| 42 | 
            +
                  describe method do
         | 
| 43 | 
            +
                    it "should raise Rack::OAuth2::Server::Resource::Bearer::Unauthorized with error = :#{error_code}" do
         | 
| 44 | 
            +
                      expect { request.send method }.to raise_error(unauthorized) { |error|
         | 
| 45 | 
            +
                        error.error.should       == error_code
         | 
| 46 | 
            +
                        error.description.should == default_description[error_code]
         | 
| 47 | 
            +
                      }
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
            end
         | 
| @@ -0,0 +1,123 @@ | |
| 1 | 
            +
            require 'spec_helper.rb'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Rack::OAuth2::Server::Resource::Bearer do
         | 
| 4 | 
            +
              let(:app) do
         | 
| 5 | 
            +
                Rack::OAuth2::Server::Resource::Bearer.new(simple_app) do |request|
         | 
| 6 | 
            +
                  case request.access_token
         | 
| 7 | 
            +
                  when 'valid_token'
         | 
| 8 | 
            +
                    bearer_token
         | 
| 9 | 
            +
                  when 'insufficient_scope_token'
         | 
| 10 | 
            +
                    request.insufficient_scope!
         | 
| 11 | 
            +
                  else
         | 
| 12 | 
            +
                    request.invalid_token!
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
              let(:bearer_token) do
         | 
| 17 | 
            +
                Rack::OAuth2::AccessToken::Bearer.new(:access_token => 'valid_token')
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
              let(:access_token) { env[Rack::OAuth2::Server::Resource::ACCESS_TOKEN] }
         | 
| 20 | 
            +
              let(:request) { app.call(env) }
         | 
| 21 | 
            +
              subject { app.call(env) }
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              shared_examples_for :authenticated_bearer_request do
         | 
| 24 | 
            +
                it 'should be authenticated' do
         | 
| 25 | 
            +
                  status, header, response = request
         | 
| 26 | 
            +
                  status.should == 200
         | 
| 27 | 
            +
                  access_token.should == bearer_token
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
              shared_examples_for :unauthorized_bearer_request do
         | 
| 31 | 
            +
                it 'should be unauthorized' do
         | 
| 32 | 
            +
                  status, header, response = request
         | 
| 33 | 
            +
                  status.should == 401
         | 
| 34 | 
            +
                  header['WWW-Authenticate'].should include 'Bearer'
         | 
| 35 | 
            +
                  access_token.should be_nil
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
              shared_examples_for :bad_bearer_request do
         | 
| 39 | 
            +
                it 'should be bad_request' do
         | 
| 40 | 
            +
                  status, header, response = request
         | 
| 41 | 
            +
                  status.should == 400
         | 
| 42 | 
            +
                  access_token.should be_nil
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
              shared_examples_for :skipped_authentication_request do
         | 
| 46 | 
            +
                it 'should skip OAuth 2.0 authentication' do
         | 
| 47 | 
            +
                  status, header, response = request
         | 
| 48 | 
            +
                  status.should == 200
         | 
| 49 | 
            +
                  access_token.should be_nil
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              context 'when no access token is given' do
         | 
| 54 | 
            +
                let(:env) { Rack::MockRequest.env_for('/protected_resource') }
         | 
| 55 | 
            +
                it_behaves_like :skipped_authentication_request
         | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              context 'when valid_token is given' do
         | 
| 59 | 
            +
                context 'when token is in Authorization header' do
         | 
| 60 | 
            +
                  let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'Bearer valid_token') }
         | 
| 61 | 
            +
                  it_behaves_like :authenticated_bearer_request
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                context 'when token is in params' do
         | 
| 65 | 
            +
                  let(:env) { Rack::MockRequest.env_for('/protected_resource', :params => {:access_token => 'valid_token'}) }
         | 
| 66 | 
            +
                  it_behaves_like :authenticated_bearer_request
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
              context 'when invalid authorization header is given' do
         | 
| 71 | 
            +
                let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => '') }
         | 
| 72 | 
            +
                it_behaves_like :skipped_authentication_request
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              context 'when invalid_token is given' do
         | 
| 76 | 
            +
                let(:env) { Rack::MockRequest.env_for('/protected_resource', 'HTTP_AUTHORIZATION' => 'Bearer invalid_token') }
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                context 'when token is in Authorization header' do
         | 
| 79 | 
            +
                  it_behaves_like :unauthorized_bearer_request
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                context 'when token is in params' do
         | 
| 83 | 
            +
                  let(:env) { Rack::MockRequest.env_for('/protected_resource', :params => {:access_token => 'invalid_token'}) }
         | 
| 84 | 
            +
                  it_behaves_like :unauthorized_bearer_request
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                describe 'realm' do
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                  context 'when specified' do
         | 
| 90 | 
            +
                    let(:realm) { 'server.example.com' }
         | 
| 91 | 
            +
                    let(:app) do
         | 
| 92 | 
            +
                      Rack::OAuth2::Server::Resource::Bearer.new(simple_app, realm) do |request|
         | 
| 93 | 
            +
                        request.unauthorized!
         | 
| 94 | 
            +
                      end
         | 
| 95 | 
            +
                    end
         | 
| 96 | 
            +
                    it 'should use specified realm' do
         | 
| 97 | 
            +
                      status, header, response = request
         | 
| 98 | 
            +
                      header['WWW-Authenticate'].should include "Bearer realm=\"#{realm}\""
         | 
| 99 | 
            +
                    end
         | 
| 100 | 
            +
                  end
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  context 'otherwize' do
         | 
| 103 | 
            +
                    it 'should use default realm' do
         | 
| 104 | 
            +
                      status, header, response = request
         | 
| 105 | 
            +
                      header['WWW-Authenticate'].should include "Bearer realm=\"#{Rack::OAuth2::Server::Resource::Bearer::DEFAULT_REALM}\""
         | 
| 106 | 
            +
                    end
         | 
| 107 | 
            +
                  end
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
              end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
              context 'when multiple access_token is given' do
         | 
| 112 | 
            +
                context 'when token is in Authorization header and params' do
         | 
| 113 | 
            +
                  let(:env) do
         | 
| 114 | 
            +
                    Rack::MockRequest.env_for(
         | 
| 115 | 
            +
                      '/protected_resource',
         | 
| 116 | 
            +
                      'HTTP_AUTHORIZATION' => 'Bearer valid_token',
         | 
| 117 | 
            +
                      :params => {:access_token => 'valid_token'}
         | 
| 118 | 
            +
                    )
         | 
| 119 | 
            +
                  end
         | 
| 120 | 
            +
                  it_behaves_like :bad_bearer_request
         | 
| 121 | 
            +
                end
         | 
| 122 | 
            +
              end
         | 
| 123 | 
            +
            end
         | 
| @@ -0,0 +1,147 @@ | |
| 1 | 
            +
            require 'spec_helper.rb'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Rack::OAuth2::Server::Resource::BadRequest do
         | 
| 4 | 
            +
              let(:error) { Rack::OAuth2::Server::Resource::BadRequest.new(:invalid_request) }
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              it { should be_a Rack::OAuth2::Server::Abstract::BadRequest }
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              describe '#finish' do
         | 
| 9 | 
            +
                it 'should respond in JSON' do
         | 
| 10 | 
            +
                  status, header, response = error.finish
         | 
| 11 | 
            +
                  status.should == 400
         | 
| 12 | 
            +
                  header['Content-Type'].should == 'application/json'
         | 
| 13 | 
            +
                  response.body.should == ['{"error":"invalid_request"}']
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            describe Rack::OAuth2::Server::Resource::Unauthorized do
         | 
| 19 | 
            +
              let(:error) { Rack::OAuth2::Server::Resource::Unauthorized.new(:invalid_token) }
         | 
| 20 | 
            +
              let(:realm) { Rack::OAuth2::Server::Resource::DEFAULT_REALM }
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              it { should be_a Rack::OAuth2::Server::Abstract::Unauthorized }
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              describe '#scheme' do
         | 
| 25 | 
            +
                it do
         | 
| 26 | 
            +
                  expect { error.scheme }.to raise_error(RuntimeError, 'Define me!')
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              context 'when scheme is defined' do
         | 
| 31 | 
            +
                let :error_with_scheme do
         | 
| 32 | 
            +
                  e = error
         | 
| 33 | 
            +
                  e.instance_eval do
         | 
| 34 | 
            +
                    def scheme
         | 
| 35 | 
            +
                      :Scheme
         | 
| 36 | 
            +
                    end
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
                  e
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                describe '#finish' do
         | 
| 42 | 
            +
                  it 'should respond in JSON' do
         | 
| 43 | 
            +
                    status, header, response = error_with_scheme.finish
         | 
| 44 | 
            +
                    status.should == 401
         | 
| 45 | 
            +
                    header['Content-Type'].should == 'application/json'
         | 
| 46 | 
            +
                    header['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\", error=\"invalid_token\""
         | 
| 47 | 
            +
                    response.body.should == ['{"error":"invalid_token"}']
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  context 'when error_code is not invalid_token' do
         | 
| 51 | 
            +
                    let(:error) { Rack::OAuth2::Server::Resource::Unauthorized.new(:something) }
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    it 'should have error_code in body but not in WWW-Authenticate header' do
         | 
| 54 | 
            +
                      status, header, response = error_with_scheme.finish
         | 
| 55 | 
            +
                      header['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\""
         | 
| 56 | 
            +
                      response.body.first.should include '"error":"something"'
         | 
| 57 | 
            +
                    end
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  context 'when realm is specified' do
         | 
| 61 | 
            +
                    let(:realm) { 'server.example.com' }
         | 
| 62 | 
            +
                    let(:error) { Rack::OAuth2::Server::Resource::Bearer::Unauthorized.new(:something, nil, :realm => realm) }
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    it 'should use given realm' do
         | 
| 65 | 
            +
                      status, header, response = error_with_scheme.finish
         | 
| 66 | 
            +
                      header['WWW-Authenticate'].should == "Scheme realm=\"#{realm}\""
         | 
| 67 | 
            +
                      response.body.first.should include '"error":"something"'
         | 
| 68 | 
            +
                    end
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
            end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
            describe Rack::OAuth2::Server::Resource::Forbidden do
         | 
| 75 | 
            +
              let(:error) { Rack::OAuth2::Server::Resource::Forbidden.new(:insufficient_scope) }
         | 
| 76 | 
            +
             | 
| 77 | 
            +
              it { should be_a Rack::OAuth2::Server::Abstract::Forbidden }
         | 
| 78 | 
            +
             | 
| 79 | 
            +
              describe '#finish' do
         | 
| 80 | 
            +
                it 'should respond in JSON' do
         | 
| 81 | 
            +
                  status, header, response = error.finish
         | 
| 82 | 
            +
                  status.should == 403
         | 
| 83 | 
            +
                  header['Content-Type'].should == 'application/json'
         | 
| 84 | 
            +
                  response.body.should == ['{"error":"insufficient_scope"}']
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
              end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
              context 'when scope option is given' do
         | 
| 89 | 
            +
                let(:error) { Rack::OAuth2::Server::Resource::Bearer::Forbidden.new(:insufficient_scope, 'Desc', :scope => [:scope1, :scope2]) }
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                it 'should have blank WWW-Authenticate header' do
         | 
| 92 | 
            +
                  status, header, response = error.finish
         | 
| 93 | 
            +
                  response.body.first.should include '"scope":"scope1 scope2"'
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
              end
         | 
| 96 | 
            +
            end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
            describe Rack::OAuth2::Server::Resource::Bearer::ErrorMethods do
         | 
| 99 | 
            +
              let(:bad_request)         { Rack::OAuth2::Server::Resource::BadRequest }
         | 
| 100 | 
            +
              let(:forbidden)           { Rack::OAuth2::Server::Resource::Forbidden }
         | 
| 101 | 
            +
              let(:redirect_uri)        { 'http://client.example.com/callback' }
         | 
| 102 | 
            +
              let(:default_description) { Rack::OAuth2::Server::Resource::ErrorMethods::DEFAULT_DESCRIPTION }
         | 
| 103 | 
            +
              let(:env)                 { Rack::MockRequest.env_for("/authorize?client_id=client_id") }
         | 
| 104 | 
            +
              let(:request)             { Rack::OAuth2::Server::Resource::Request.new env }
         | 
| 105 | 
            +
             | 
| 106 | 
            +
              describe 'bad_request!' do
         | 
| 107 | 
            +
                it do
         | 
| 108 | 
            +
                  expect { request.bad_request! :invalid_request }.to raise_error bad_request
         | 
| 109 | 
            +
                end
         | 
| 110 | 
            +
              end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
              describe 'unauthorized!' do
         | 
| 113 | 
            +
                it do
         | 
| 114 | 
            +
                  expect { request.unauthorized! :invalid_client }.to raise_error(RuntimeError, 'Define me!')
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
              end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
              Rack::OAuth2::Server::Resource::ErrorMethods::DEFAULT_DESCRIPTION.keys.each do |error_code|
         | 
| 119 | 
            +
                method = "#{error_code}!"
         | 
| 120 | 
            +
                case error_code
         | 
| 121 | 
            +
                when :invalid_request
         | 
| 122 | 
            +
                  describe method do
         | 
| 123 | 
            +
                    it "should raise Rack::OAuth2::Server::Resource::BadRequest with error = :#{error_code}" do
         | 
| 124 | 
            +
                      expect { request.send method }.to raise_error(bad_request) { |error|
         | 
| 125 | 
            +
                        error.error.should       == error_code
         | 
| 126 | 
            +
                        error.description.should == default_description[error_code]
         | 
| 127 | 
            +
                      }
         | 
| 128 | 
            +
                    end
         | 
| 129 | 
            +
                  end
         | 
| 130 | 
            +
                when :insufficient_scope
         | 
| 131 | 
            +
                  describe method do
         | 
| 132 | 
            +
                    it "should raise Rack::OAuth2::Server::Resource::Forbidden with error = :#{error_code}" do
         | 
| 133 | 
            +
                      expect { request.send method }.to raise_error(forbidden) { |error|
         | 
| 134 | 
            +
                        error.error.should       == error_code
         | 
| 135 | 
            +
                        error.description.should == default_description[error_code]
         | 
| 136 | 
            +
                      }
         | 
| 137 | 
            +
                    end
         | 
| 138 | 
            +
                  end
         | 
| 139 | 
            +
                else
         | 
| 140 | 
            +
                  describe method do
         | 
| 141 | 
            +
                    it do
         | 
| 142 | 
            +
                      expect { request.send method }.to raise_error(RuntimeError, 'Define me!')
         | 
| 143 | 
            +
                    end
         | 
| 144 | 
            +
                  end
         | 
| 145 | 
            +
                end
         | 
| 146 | 
            +
              end
         | 
| 147 | 
            +
            end
         |