oauth2-rack 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +13 -0
 - data/.rspec +1 -0
 - data/Gemfile +7 -0
 - data/Guardfile +10 -0
 - data/Rakefile +4 -0
 - data/config.ru +50 -0
 - data/examples/ruby-client/password_authorization.rb +6 -0
 - data/lib/oauth2/rack/authentication/client/http_basic.rb +61 -0
 - data/lib/oauth2/rack/authentication/client/request_params.rb +55 -0
 - data/lib/oauth2/rack/authentication/client.rb +5 -0
 - data/lib/oauth2/rack/authentication/resource_owner/request_params.rb +54 -0
 - data/lib/oauth2/rack/authentication/resource_owner.rb +4 -0
 - data/lib/oauth2/rack/authentication.rb +6 -0
 - data/lib/oauth2/rack/authorization/client_credentials/access_token_issuer.rb +58 -0
 - data/lib/oauth2/rack/authorization/client_credentials.rb +5 -0
 - data/lib/oauth2/rack/authorization/password/access_token_issuer.rb +60 -0
 - data/lib/oauth2/rack/authorization/password.rb +5 -0
 - data/lib/oauth2/rack/authorization.rb +6 -0
 - data/lib/oauth2/rack.rb +9 -0
 - data/lib/oauth2-rack.rb +1 -0
 - data/spec/oauth2/rack/authentication/client/http_basic_spec.rb +76 -0
 - data/spec/oauth2/rack/authentication/client/request_params_spec.rb +86 -0
 - data/spec/oauth2/rack/authentication/resource_owner/request_params_spec.rb +86 -0
 - data/spec/oauth2/rack/authorization/client_credentials/access_token_issuer_spec.rb +99 -0
 - data/spec/oauth2/rack/authorization/password/access_token_issuer_spec.rb +101 -0
 - data/spec/spec_helper.rb +11 -0
 - data/spec/support/rake_test_helper.rb +97 -0
 - metadata +167 -0
 
    
        data/.gitignore
    ADDED
    
    
    
        data/.rspec
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --colour
         
     | 
    
        data/Gemfile
    ADDED
    
    
    
        data/Guardfile
    ADDED
    
    | 
         @@ -0,0 +1,10 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- ruby -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            # More info at https://github.com/guard/guard#readme
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            guard 'rspec', :version => 2 do
         
     | 
| 
      
 5 
     | 
    
         
            +
              watch(%r{^spec/.+_spec\.rb$})
         
     | 
| 
      
 6 
     | 
    
         
            +
              watch(%r{^lib/(.+)\.rb$})                           { |m| "spec/#{m[1]}_spec.rb" }
         
     | 
| 
      
 7 
     | 
    
         
            +
              watch(%r{^spec/support/(.+)\.rb$})                  { "spec/" }
         
     | 
| 
      
 8 
     | 
    
         
            +
              watch('spec/spec_helper.rb')                        { "spec/" }
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
    
        data/Rakefile
    ADDED
    
    
    
        data/config.ru
    ADDED
    
    | 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            $: << File.expand_path('../lib', __FILE__)
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'oauth2/rack'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            class AccessTokenIssuer
         
     | 
| 
      
 5 
     | 
    
         
            +
              def self.call(opts = {})
         
     | 
| 
      
 6 
     | 
    
         
            +
                opts.merge('access_token' => 'test')
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
            end
         
     | 
| 
      
 9 
     | 
    
         
            +
            class Authenticator
         
     | 
| 
      
 10 
     | 
    
         
            +
              def self.call(opts = {})
         
     | 
| 
      
 11 
     | 
    
         
            +
                if opts[:username]
         
     | 
| 
      
 12 
     | 
    
         
            +
                  authenticate_resource_owner(opts)
         
     | 
| 
      
 13 
     | 
    
         
            +
                elsif opts[:client_id]
         
     | 
| 
      
 14 
     | 
    
         
            +
                  authenticate_client(opts)
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              def self.authenticate_resource_owner(opts)
         
     | 
| 
      
 19 
     | 
    
         
            +
                OpenStruct.new(:username => opts[:username])
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              def self.authenticate_client(opts)
         
     | 
| 
      
 23 
     | 
    
         
            +
                OpenStruct.new(:client_id => opts[:client_id])
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            map '/password/access_token' do
         
     | 
| 
      
 28 
     | 
    
         
            +
              use OAuth2::Rack::Authentication::Client::HTTPBasic, :required => false, :authenticator => Authenticator
         
     | 
| 
      
 29 
     | 
    
         
            +
              use OAuth2::Rack::Authentication::Client::RequestParams, :required => false, :authenticator => Authenticator
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              use OAuth2::Rack::Authentication::ResourceOwner::RequestParams, :authenticator => Authenticator
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              use OAuth2::Rack::Authorization::Password::AccessTokenIssuer, :issuer => AccessTokenIssuer
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              run proc { |env| [200, {'Content-Type' => 'text/html'}, ['Hello']] }
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            map '/client_credentials/access_token' do
         
     | 
| 
      
 39 
     | 
    
         
            +
              use OAuth2::Rack::Authentication::Client::HTTPBasic, :required => false, :authenticator => Authenticator
         
     | 
| 
      
 40 
     | 
    
         
            +
              use OAuth2::Rack::Authentication::Client::RequestParams, :required => false, :authenticator => Authenticator
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              use OAuth2::Rack::Authorization::ClientCredentials::AccessTokenIssuer, :issuer => AccessTokenIssuer
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              run proc { |env| [200, {'Content-Type' => 'text/html'}, ['Hello']] }
         
     | 
| 
      
 45 
     | 
    
         
            +
            end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            map '/inspect' do
         
     | 
| 
      
 49 
     | 
    
         
            +
              run proc { |env| [200, {'Content-Type' => 'text/html'}, [env.inspect]] }
         
     | 
| 
      
 50 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,61 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'oauth2/rack'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # 2.4.1. Client Password
         
     | 
| 
      
 4 
     | 
    
         
            +
            class OAuth2::Rack::Authentication::Client::HTTPBasic
         
     | 
| 
      
 5 
     | 
    
         
            +
              HEADER_KEYS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION']
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              def initialize(app, opts = {}, &authenticator)
         
     | 
| 
      
 8 
     | 
    
         
            +
                @app = app
         
     | 
| 
      
 9 
     | 
    
         
            +
                @realm = opts.delete(:realm)
         
     | 
| 
      
 10 
     | 
    
         
            +
                @required = opts.fetch(:required, true)
         
     | 
| 
      
 11 
     | 
    
         
            +
                opts.delete(:required)
         
     | 
| 
      
 12 
     | 
    
         
            +
                @authenticator = authenticator || opts.delete(:authenticator)
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              def call(env)
         
     | 
| 
      
 16 
     | 
    
         
            +
                return @app.call(env) if env.has_key?('oauth2.client')
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                key = HEADER_KEYS.find { |k| env.has_key?(k) }
         
     | 
| 
      
 19 
     | 
    
         
            +
                auth_string = env[key]
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                if auth_string.nil?
         
     | 
| 
      
 22 
     | 
    
         
            +
                  return @required ? unauthorized : @app.call(env)
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                schema, credentials = auth_string.split(' ', 2)
         
     | 
| 
      
 26 
     | 
    
         
            +
                if schema.downcase != 'basic'
         
     | 
| 
      
 27 
     | 
    
         
            +
                  return bad_request
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                client_id, client_secret = credentials.unpack('m*').first.split(':', 2)
         
     | 
| 
      
 31 
     | 
    
         
            +
                client = @authenticator.call(:client_id => client_id, :client_secret => client_secret)
         
     | 
| 
      
 32 
     | 
    
         
            +
                if client
         
     | 
| 
      
 33 
     | 
    
         
            +
                  env['oauth2.client'] = client
         
     | 
| 
      
 34 
     | 
    
         
            +
                  @app.call(env)
         
     | 
| 
      
 35 
     | 
    
         
            +
                else
         
     | 
| 
      
 36 
     | 
    
         
            +
                  unauthorized
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              private
         
     | 
| 
      
 41 
     | 
    
         
            +
              def authenticate(opts)
         
     | 
| 
      
 42 
     | 
    
         
            +
                @authenticator && @authenticator.call(opts)
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              def unauthorized
         
     | 
| 
      
 46 
     | 
    
         
            +
                [ 401,
         
     | 
| 
      
 47 
     | 
    
         
            +
                  { 'Content-Type' => 'text/plain',
         
     | 
| 
      
 48 
     | 
    
         
            +
                    'Content-Length' => '0',
         
     | 
| 
      
 49 
     | 
    
         
            +
                    'WWW-Authenticate' => 'Basic realm="%s"' % @realm },
         
     | 
| 
      
 50 
     | 
    
         
            +
                  []
         
     | 
| 
      
 51 
     | 
    
         
            +
                ]
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
              def bad_request
         
     | 
| 
      
 55 
     | 
    
         
            +
                [ 400,
         
     | 
| 
      
 56 
     | 
    
         
            +
                  { 'Content-Type' => 'text/plain',
         
     | 
| 
      
 57 
     | 
    
         
            +
                    'Content-Length' => '0' },
         
     | 
| 
      
 58 
     | 
    
         
            +
                  []
         
     | 
| 
      
 59 
     | 
    
         
            +
                ]
         
     | 
| 
      
 60 
     | 
    
         
            +
              end
         
     | 
| 
      
 61 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,55 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'oauth2/rack'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # 2.4.1. Client Password
         
     | 
| 
      
 4 
     | 
    
         
            +
            # Send client_id and client_secret in request params
         
     | 
| 
      
 5 
     | 
    
         
            +
            class OAuth2::Rack::Authentication::Client::RequestParams
         
     | 
| 
      
 6 
     | 
    
         
            +
              def initialize(app, opts = {}, &authenticator)
         
     | 
| 
      
 7 
     | 
    
         
            +
                @app = app
         
     | 
| 
      
 8 
     | 
    
         
            +
                @required = opts.fetch(:required, true)
         
     | 
| 
      
 9 
     | 
    
         
            +
                opts.delete(:required)
         
     | 
| 
      
 10 
     | 
    
         
            +
                @authenticator = authenticator || opts.delete(:authenticator)
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              def call(env)
         
     | 
| 
      
 14 
     | 
    
         
            +
                return @app.call(env) if env.has_key?('oauth2.client')
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                @request = Rack::Request.new(env)
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                client_id = @request['client_id']
         
     | 
| 
      
 19 
     | 
    
         
            +
                client_secret = @request['client_secret']
         
     | 
| 
      
 20 
     | 
    
         
            +
                if client_id.nil? && client_secret.nil?
         
     | 
| 
      
 21 
     | 
    
         
            +
                  return @required ? unauthorized : @app.call(env)
         
     | 
| 
      
 22 
     | 
    
         
            +
                elsif client_id.nil? || client_secret.nil?
         
     | 
| 
      
 23 
     | 
    
         
            +
                  return bad_request
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                client = @authenticator.call(:client_id => client_id, :client_secret => client_secret)
         
     | 
| 
      
 27 
     | 
    
         
            +
                if client
         
     | 
| 
      
 28 
     | 
    
         
            +
                  env['oauth2.client'] = client
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @app.call(env)
         
     | 
| 
      
 30 
     | 
    
         
            +
                else
         
     | 
| 
      
 31 
     | 
    
         
            +
                  unauthorized
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
              
         
     | 
| 
      
 35 
     | 
    
         
            +
              private
         
     | 
| 
      
 36 
     | 
    
         
            +
              def authenticate(opts)
         
     | 
| 
      
 37 
     | 
    
         
            +
                @authenticator && @authenticator.call(opts)
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def unauthorized
         
     | 
| 
      
 41 
     | 
    
         
            +
                [ 401,
         
     | 
| 
      
 42 
     | 
    
         
            +
                  { 'Content-Type' => 'text/plain',
         
     | 
| 
      
 43 
     | 
    
         
            +
                    'Content-Length' => '0' },
         
     | 
| 
      
 44 
     | 
    
         
            +
                  []
         
     | 
| 
      
 45 
     | 
    
         
            +
                ]
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              def bad_request
         
     | 
| 
      
 49 
     | 
    
         
            +
                [ 400,
         
     | 
| 
      
 50 
     | 
    
         
            +
                  { 'Content-Type' => 'text/plain',
         
     | 
| 
      
 51 
     | 
    
         
            +
                    'Content-Length' => '0' },
         
     | 
| 
      
 52 
     | 
    
         
            +
                  []
         
     | 
| 
      
 53 
     | 
    
         
            +
                ]
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,54 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'oauth2/rack'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Authenticate resource owner with request params
         
     | 
| 
      
 4 
     | 
    
         
            +
            class OAuth2::Rack::Authentication::ResourceOwner::RequestParams
         
     | 
| 
      
 5 
     | 
    
         
            +
              def initialize(app, opts = {}, &authenticator)
         
     | 
| 
      
 6 
     | 
    
         
            +
                @app = app
         
     | 
| 
      
 7 
     | 
    
         
            +
                @required = opts.fetch(:required, true)
         
     | 
| 
      
 8 
     | 
    
         
            +
                opts.delete(:required)
         
     | 
| 
      
 9 
     | 
    
         
            +
                @authenticator = authenticator || opts.delete(:authenticator)
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              def call(env)
         
     | 
| 
      
 13 
     | 
    
         
            +
                return @app.call(env) if env.has_key?('oauth2.resource_owner')
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                @request = Rack::Request.new(env)
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                username = @request['username']
         
     | 
| 
      
 18 
     | 
    
         
            +
                password = @request['password']
         
     | 
| 
      
 19 
     | 
    
         
            +
                if username.nil? && password.nil?
         
     | 
| 
      
 20 
     | 
    
         
            +
                  return @required ? unauthorized : @app.call(env)
         
     | 
| 
      
 21 
     | 
    
         
            +
                elsif username.nil? || password.nil?
         
     | 
| 
      
 22 
     | 
    
         
            +
                  return bad_request
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                resource_owner = @authenticator.call(:username => username, :password => password)
         
     | 
| 
      
 26 
     | 
    
         
            +
                if resource_owner
         
     | 
| 
      
 27 
     | 
    
         
            +
                  env['oauth2.resource_owner'] = resource_owner
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @app.call(env)
         
     | 
| 
      
 29 
     | 
    
         
            +
                else
         
     | 
| 
      
 30 
     | 
    
         
            +
                  unauthorized
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
              
         
     | 
| 
      
 34 
     | 
    
         
            +
              private
         
     | 
| 
      
 35 
     | 
    
         
            +
              def authenticate(opts)
         
     | 
| 
      
 36 
     | 
    
         
            +
                @authenticator && @authenticator.call(opts)
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              def unauthorized
         
     | 
| 
      
 40 
     | 
    
         
            +
                [ 401,
         
     | 
| 
      
 41 
     | 
    
         
            +
                  { 'Content-Type' => 'text/plain',
         
     | 
| 
      
 42 
     | 
    
         
            +
                    'Content-Length' => '0' },
         
     | 
| 
      
 43 
     | 
    
         
            +
                  []
         
     | 
| 
      
 44 
     | 
    
         
            +
                ]
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
              
         
     | 
| 
      
 47 
     | 
    
         
            +
              def bad_request
         
     | 
| 
      
 48 
     | 
    
         
            +
                [ 400,
         
     | 
| 
      
 49 
     | 
    
         
            +
                  { 'Content-Type' => 'text/plain',
         
     | 
| 
      
 50 
     | 
    
         
            +
                    'Content-Length' => '0' },
         
     | 
| 
      
 51 
     | 
    
         
            +
                  []
         
     | 
| 
      
 52 
     | 
    
         
            +
                ]
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,58 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # @see 4.4.1 Client Credentials
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'oauth2/rack'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'multi_json'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class OAuth2::Rack::Authorization::ClientCredentials::AccessTokenIssuer
         
     | 
| 
      
 6 
     | 
    
         
            +
              def initialize(app, opts = {}, &issuer)
         
     | 
| 
      
 7 
     | 
    
         
            +
                @app = app
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                @issuer = issuer || opts.delete(:issuer)
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              def call(env)
         
     | 
| 
      
 13 
     | 
    
         
            +
                client = env['oauth2.client']
         
     | 
| 
      
 14 
     | 
    
         
            +
                unless client
         
     | 
| 
      
 15 
     | 
    
         
            +
                  return error_response(:error => 'invalid_client')
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                request = Rack::Request.new(env)
         
     | 
| 
      
 19 
     | 
    
         
            +
                unless request['grant_type'] == 'client_credentials'
         
     | 
| 
      
 20 
     | 
    
         
            +
                  return error_response(:error => 'invalid_request')
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                access_token = find_acccess_token(:grant_type => 'client_credentials',
         
     | 
| 
      
 24 
     | 
    
         
            +
                                                  :client => client,
         
     | 
| 
      
 25 
     | 
    
         
            +
                                                  :scope => request['scope'])
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                if access_token['error']
         
     | 
| 
      
 28 
     | 
    
         
            +
                  error_response(access_token)
         
     | 
| 
      
 29 
     | 
    
         
            +
                else
         
     | 
| 
      
 30 
     | 
    
         
            +
                  successful_response(access_token)
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              private
         
     | 
| 
      
 35 
     | 
    
         
            +
              def find_acccess_token(opts)
         
     | 
| 
      
 36 
     | 
    
         
            +
                if @issuer
         
     | 
| 
      
 37 
     | 
    
         
            +
                  @issuer.call(opts)
         
     | 
| 
      
 38 
     | 
    
         
            +
                end || { 'error' => 'unauthorized_client' }
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              def successful_response(response_object)
         
     | 
| 
      
 42 
     | 
    
         
            +
                headers = {
         
     | 
| 
      
 43 
     | 
    
         
            +
                  'Content-Type' => 'application/json;charset=UTF-8',
         
     | 
| 
      
 44 
     | 
    
         
            +
                  'Cache-Control' => 'no-store',
         
     | 
| 
      
 45 
     | 
    
         
            +
                  'Pragma' => 'no-cache'
         
     | 
| 
      
 46 
     | 
    
         
            +
                }
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                [200, headers, [MultiJson.encode(response_object)]]
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              def error_response(response_object)
         
     | 
| 
      
 52 
     | 
    
         
            +
                headers = {
         
     | 
| 
      
 53 
     | 
    
         
            +
                  'Content-Type' => 'application/json;charset=UTF-8'
         
     | 
| 
      
 54 
     | 
    
         
            +
                }
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                [400, headers, [MultiJson.encode(response_object)]]
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,60 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # @see 4.3. Resource Owner Password Credentials
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'oauth2/rack'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'multi_json'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class OAuth2::Rack::Authorization::Password::AccessTokenIssuer
         
     | 
| 
      
 6 
     | 
    
         
            +
              def initialize(app, opts = {}, &issuer)
         
     | 
| 
      
 7 
     | 
    
         
            +
                @app = app
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                @issuer = issuer || opts.delete(:issuer)
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              def call(env)
         
     | 
| 
      
 13 
     | 
    
         
            +
                resource_owner = env['oauth2.resource_owner']
         
     | 
| 
      
 14 
     | 
    
         
            +
                unless resource_owner
         
     | 
| 
      
 15 
     | 
    
         
            +
                  return error_response(:error => 'invalid_grant')
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                request = Rack::Request.new(env)
         
     | 
| 
      
 19 
     | 
    
         
            +
                unless request['grant_type'] == 'password'
         
     | 
| 
      
 20 
     | 
    
         
            +
                  return error_response(:error => 'invalid_request')
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                # oauth2.client is set in client authentication
         
     | 
| 
      
 24 
     | 
    
         
            +
                access_token = find_acccess_token(:grant_type => 'password',
         
     | 
| 
      
 25 
     | 
    
         
            +
                                                  :resource_owner => resource_owner,
         
     | 
| 
      
 26 
     | 
    
         
            +
                                                  :client => env['oath2.client'],
         
     | 
| 
      
 27 
     | 
    
         
            +
                                                  :scope => request['scope'])
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                if access_token['error']
         
     | 
| 
      
 30 
     | 
    
         
            +
                  error_response(access_token)
         
     | 
| 
      
 31 
     | 
    
         
            +
                else
         
     | 
| 
      
 32 
     | 
    
         
            +
                  successful_response(access_token)
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              private
         
     | 
| 
      
 37 
     | 
    
         
            +
              def find_acccess_token(opts)
         
     | 
| 
      
 38 
     | 
    
         
            +
                if @issuer
         
     | 
| 
      
 39 
     | 
    
         
            +
                  @issuer.call(opts)
         
     | 
| 
      
 40 
     | 
    
         
            +
                end || { 'error' => 'unauthorized_client' }
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              def successful_response(response_object)
         
     | 
| 
      
 44 
     | 
    
         
            +
                headers = {
         
     | 
| 
      
 45 
     | 
    
         
            +
                  'Content-Type' => 'application/json;charset=UTF-8',
         
     | 
| 
      
 46 
     | 
    
         
            +
                  'Cache-Control' => 'no-store',
         
     | 
| 
      
 47 
     | 
    
         
            +
                  'Pragma' => 'no-cache'
         
     | 
| 
      
 48 
     | 
    
         
            +
                }
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                [200, headers, [MultiJson.encode(response_object)]]
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              def error_response(response_object)
         
     | 
| 
      
 54 
     | 
    
         
            +
                headers = {
         
     | 
| 
      
 55 
     | 
    
         
            +
                  'Content-Type' => 'application/json;charset=UTF-8'
         
     | 
| 
      
 56 
     | 
    
         
            +
                }
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                [400, headers, [MultiJson.encode(response_object)]]
         
     | 
| 
      
 59 
     | 
    
         
            +
              end
         
     | 
| 
      
 60 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/oauth2/rack.rb
    ADDED
    
    | 
         @@ -0,0 +1,9 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'oauth2/rack/version'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module OAuth2
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Oauth2::Rack module, the top namespace for all oauth2-rack modules and classes
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Rack
         
     | 
| 
      
 6 
     | 
    
         
            +
                autoload :Authorization, 'oauth2/rack/authorization'
         
     | 
| 
      
 7 
     | 
    
         
            +
                autoload :Authentication, 'oauth2/rack/authentication'
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/oauth2-rack.rb
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'oauth2/rack'
         
     | 
| 
         @@ -0,0 +1,76 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe OAuth2::Rack::Authentication::Client::HTTPBasic do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:client) { double('client').as_null_object }
         
     | 
| 
      
 5 
     | 
    
         
            +
              let(:authenticator) { double('authenticator').as_null_object }
         
     | 
| 
      
 6 
     | 
    
         
            +
              let(:opts) { Hash.new }
         
     | 
| 
      
 7 
     | 
    
         
            +
              let(:chained_app_response) { [200, { 'Content-Type' => 'text/plain' }, []] }
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              def do_request
         
     | 
| 
      
 10 
     | 
    
         
            +
                post '/', opts
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              context 'when oauth2.client is already set' do
         
     | 
| 
      
 14 
     | 
    
         
            +
                it 'continues the app' do
         
     | 
| 
      
 15 
     | 
    
         
            +
                  opts['oauth2.client'] = client
         
     | 
| 
      
 16 
     | 
    
         
            +
                  chained_app.should_receive(:call).with(hash_including('oauth2.client' => client)).and_return(chained_app_response)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  do_request
         
     | 
| 
      
 18 
     | 
    
         
            +
                  response.status.should eq(200)
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              context 'when auth header is not specified' do
         
     | 
| 
      
 23 
     | 
    
         
            +
                context 'and http basic auth is required' do
         
     | 
| 
      
 24 
     | 
    
         
            +
                  it 'responds with 401 unauthorized' do
         
     | 
| 
      
 25 
     | 
    
         
            +
                    do_request
         
     | 
| 
      
 26 
     | 
    
         
            +
                    response.status.should eq(401)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
                context 'and http basic auth is optional' do
         
     | 
| 
      
 30 
     | 
    
         
            +
                  app { OAuth2::Rack::Authentication::Client::HTTPBasic.new(chained_app, :required => false) }
         
     | 
| 
      
 31 
     | 
    
         
            +
                  it 'continues the app' do
         
     | 
| 
      
 32 
     | 
    
         
            +
                    chained_app.should_receive(:call).with(hash_not_including('oauth2.client')).and_return(chained_app_response)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    do_request
         
     | 
| 
      
 34 
     | 
    
         
            +
                    response.status.should eq(200)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              context 'when schema is not basic' do
         
     | 
| 
      
 40 
     | 
    
         
            +
                before { opts['HTTP_AUTHORIZATION'] = 'Digest xxx' }
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                it 'responds with 400 bad request' do
         
     | 
| 
      
 43 
     | 
    
         
            +
                  do_request
         
     | 
| 
      
 44 
     | 
    
         
            +
                  response.status.should eq(400)
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              context 'when schema is basic' do
         
     | 
| 
      
 49 
     | 
    
         
            +
                app {
         
     | 
| 
      
 50 
     | 
    
         
            +
                  OAuth2::Rack::Authentication::Client::HTTPBasic.new(chained_app) do |opts|
         
     | 
| 
      
 51 
     | 
    
         
            +
                    authenticator.call(opts)
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
                }
         
     | 
| 
      
 54 
     | 
    
         
            +
                before { opts['HTTP_AUTHORIZATION'] = "Basic #{["user:pass"].pack('m*')}" }
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                context 'and credentials are valid' do
         
     | 
| 
      
 57 
     | 
    
         
            +
                  it 'sets oauth2.client in env' do
         
     | 
| 
      
 58 
     | 
    
         
            +
                    authenticator.should_receive(:call).with(:client_id => 'user', :client_secret => 'pass').and_return(client)
         
     | 
| 
      
 59 
     | 
    
         
            +
                    chained_app.should_receive(:call).with(hash_including('oauth2.client' => client)).and_return(chained_app_response)
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                    do_request
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                context 'but credentials are invalid' do
         
     | 
| 
      
 66 
     | 
    
         
            +
                  it 'responds with 401 unauthorized' do
         
     | 
| 
      
 67 
     | 
    
         
            +
                    authenticator.should_receive(:call).with(:client_id => 'user', :client_secret => 'pass').and_return(nil)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    chained_app.should_not_receive(:call)
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                    do_request
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                    response.status.should eq(401)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
                end
         
     | 
| 
      
 75 
     | 
    
         
            +
              end
         
     | 
| 
      
 76 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,86 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe OAuth2::Rack::Authentication::Client::RequestParams do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:client) { double('client').as_null_object }
         
     | 
| 
      
 5 
     | 
    
         
            +
              let(:authenticator) { double('authenticator').as_null_object }
         
     | 
| 
      
 6 
     | 
    
         
            +
              let(:params) { Hash.new }
         
     | 
| 
      
 7 
     | 
    
         
            +
              let(:opts) { Hash[:params => params] }
         
     | 
| 
      
 8 
     | 
    
         
            +
              let(:chained_app_response) { [200, { 'Content-Type' => 'text/plain' }, []] }
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              def do_request
         
     | 
| 
      
 11 
     | 
    
         
            +
                post '/', opts
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              context 'when oauth2.client is already set' do
         
     | 
| 
      
 15 
     | 
    
         
            +
                it 'continues the app' do
         
     | 
| 
      
 16 
     | 
    
         
            +
                  opts['oauth2.client'] = client
         
     | 
| 
      
 17 
     | 
    
         
            +
                  chained_app.should_receive(:call).with(hash_including('oauth2.client' => client)).and_return(chained_app_response)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  do_request
         
     | 
| 
      
 19 
     | 
    
         
            +
                  response.status.should eq(200)
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              context 'when client_id and client_secret are both missed' do
         
     | 
| 
      
 24 
     | 
    
         
            +
                context 'and request params auth is required' do
         
     | 
| 
      
 25 
     | 
    
         
            +
                  it 'responds with 401 unauthorized' do
         
     | 
| 
      
 26 
     | 
    
         
            +
                    do_request
         
     | 
| 
      
 27 
     | 
    
         
            +
                    response.status.should eq(401)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
                context 'and request params auth is optional' do
         
     | 
| 
      
 31 
     | 
    
         
            +
                  app { OAuth2::Rack::Authentication::Client::RequestParams.new(chained_app, :required => false) }
         
     | 
| 
      
 32 
     | 
    
         
            +
                  it 'continues the app' do
         
     | 
| 
      
 33 
     | 
    
         
            +
                    chained_app.should_receive(:call).with(hash_not_including('oauth2.client')).and_return(chained_app_response)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    do_request
         
     | 
| 
      
 35 
     | 
    
         
            +
                    response.status.should eq(200)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              context 'when client_id is missed' do
         
     | 
| 
      
 41 
     | 
    
         
            +
                before { params['client_secret'] = 'secret' }
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                it 'responds with 400 bad request' do
         
     | 
| 
      
 44 
     | 
    
         
            +
                  do_request
         
     | 
| 
      
 45 
     | 
    
         
            +
                  response.status.should eq(400)
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
              context 'when client_secret is missed' do
         
     | 
| 
      
 49 
     | 
    
         
            +
                before { params['client_id'] = 'client_x' }
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                it 'responds with 400 bad request' do
         
     | 
| 
      
 52 
     | 
    
         
            +
                  do_request
         
     | 
| 
      
 53 
     | 
    
         
            +
                  response.status.should eq(400)
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
              context 'when client_id and client_secret are specified' do
         
     | 
| 
      
 58 
     | 
    
         
            +
                app {
         
     | 
| 
      
 59 
     | 
    
         
            +
                  OAuth2::Rack::Authentication::Client::RequestParams.new(chained_app) do |opts|
         
     | 
| 
      
 60 
     | 
    
         
            +
                    authenticator.call(opts)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                }
         
     | 
| 
      
 63 
     | 
    
         
            +
                let(:credentials) { Hash[:client_id => 'client_x', :client_secret => 'secret'] }
         
     | 
| 
      
 64 
     | 
    
         
            +
                before { params.merge! credentials }
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                context 'and credentials are valid' do
         
     | 
| 
      
 67 
     | 
    
         
            +
                  it 'sets oauth2.client in env' do
         
     | 
| 
      
 68 
     | 
    
         
            +
                    authenticator.should_receive(:call).with(credentials).and_return(client)
         
     | 
| 
      
 69 
     | 
    
         
            +
                    chained_app.should_receive(:call).with(hash_including('oauth2.client' => client)).and_return(chained_app_response)
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    do_request
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                context 'but credentials are invalid' do
         
     | 
| 
      
 76 
     | 
    
         
            +
                  it 'responds with 401 unauthorized' do
         
     | 
| 
      
 77 
     | 
    
         
            +
                    authenticator.should_receive(:call).with(credentials).and_return(nil)
         
     | 
| 
      
 78 
     | 
    
         
            +
                    chained_app.should_not_receive(:call)
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                    do_request
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                    response.status.should eq(401)
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
              end
         
     | 
| 
      
 86 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,86 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe OAuth2::Rack::Authentication::ResourceOwner::RequestParams do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:resource_owner) { double('resource_owner').as_null_object }
         
     | 
| 
      
 5 
     | 
    
         
            +
              let(:authenticator) { double('authenticator').as_null_object }
         
     | 
| 
      
 6 
     | 
    
         
            +
              let(:params) { Hash.new }
         
     | 
| 
      
 7 
     | 
    
         
            +
              let(:opts) { Hash[:params => params] }
         
     | 
| 
      
 8 
     | 
    
         
            +
              let(:chained_app_response) { [200, { 'Content-Type' => 'text/plain' }, []] }
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              def do_request
         
     | 
| 
      
 11 
     | 
    
         
            +
                post '/', opts
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              context 'when oauth2.resource_owner is already set' do
         
     | 
| 
      
 15 
     | 
    
         
            +
                it 'continues the app' do
         
     | 
| 
      
 16 
     | 
    
         
            +
                  opts['oauth2.resource_owner'] = resource_owner
         
     | 
| 
      
 17 
     | 
    
         
            +
                  chained_app.should_receive(:call).with(hash_including('oauth2.resource_owner' => resource_owner)).and_return(chained_app_response)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  do_request
         
     | 
| 
      
 19 
     | 
    
         
            +
                  response.status.should eq(200)
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              context 'when username and password are both missed' do
         
     | 
| 
      
 24 
     | 
    
         
            +
                context 'and request params auth is required' do
         
     | 
| 
      
 25 
     | 
    
         
            +
                  it 'responds with 401 unauthorized' do
         
     | 
| 
      
 26 
     | 
    
         
            +
                    do_request
         
     | 
| 
      
 27 
     | 
    
         
            +
                    response.status.should eq(401)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
                context 'and request params auth is optional' do
         
     | 
| 
      
 31 
     | 
    
         
            +
                  app { OAuth2::Rack::Authentication::ResourceOwner::RequestParams.new(chained_app, :required => false) }
         
     | 
| 
      
 32 
     | 
    
         
            +
                  it 'continues the app' do
         
     | 
| 
      
 33 
     | 
    
         
            +
                    chained_app.should_receive(:call).with(hash_not_including('oauth2.resource_owner')).and_return(chained_app_response)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    do_request
         
     | 
| 
      
 35 
     | 
    
         
            +
                    response.status.should eq(200)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              context 'when username is missed' do
         
     | 
| 
      
 41 
     | 
    
         
            +
                before { params['password'] = 'secret' }
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                it 'responds with 400 bad request' do
         
     | 
| 
      
 44 
     | 
    
         
            +
                  do_request
         
     | 
| 
      
 45 
     | 
    
         
            +
                  response.status.should eq(400)
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
              context 'when password is missed' do
         
     | 
| 
      
 49 
     | 
    
         
            +
                before { params['username'] = 'user_x' }
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                it 'responds with 400 bad request' do
         
     | 
| 
      
 52 
     | 
    
         
            +
                  do_request
         
     | 
| 
      
 53 
     | 
    
         
            +
                  response.status.should eq(400)
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
              context 'when username and password are specified' do
         
     | 
| 
      
 58 
     | 
    
         
            +
                app {
         
     | 
| 
      
 59 
     | 
    
         
            +
                  OAuth2::Rack::Authentication::ResourceOwner::RequestParams.new(chained_app) do |opts|
         
     | 
| 
      
 60 
     | 
    
         
            +
                    authenticator.call(opts)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                }
         
     | 
| 
      
 63 
     | 
    
         
            +
                let(:credentials) { Hash[:username => 'user_x', :password => 'secret'] }
         
     | 
| 
      
 64 
     | 
    
         
            +
                before { params.merge! credentials }
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                context 'and credentials are valid' do
         
     | 
| 
      
 67 
     | 
    
         
            +
                  it 'sets oauth2.resource_owner in env' do
         
     | 
| 
      
 68 
     | 
    
         
            +
                    authenticator.should_receive(:call).with(credentials).and_return(resource_owner)
         
     | 
| 
      
 69 
     | 
    
         
            +
                    chained_app.should_receive(:call).with(hash_including('oauth2.resource_owner' => resource_owner)).and_return(chained_app_response)
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    do_request
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                context 'but credentials are invalid' do
         
     | 
| 
      
 76 
     | 
    
         
            +
                  it 'responds with 401 unauthorized' do
         
     | 
| 
      
 77 
     | 
    
         
            +
                    authenticator.should_receive(:call).with(credentials).and_return(nil)
         
     | 
| 
      
 78 
     | 
    
         
            +
                    chained_app.should_not_receive(:call)
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                    do_request
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                    response.status.should eq(401)
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
              end
         
     | 
| 
      
 86 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,99 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe OAuth2::Rack::Authorization::ClientCredentials::AccessTokenIssuer do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:client) { double('client') }
         
     | 
| 
      
 5 
     | 
    
         
            +
              let(:opts) { Hash.new }
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              def do_request
         
     | 
| 
      
 8 
     | 
    
         
            +
                post '/', opts
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              context 'when client is authenticated' do
         
     | 
| 
      
 12 
     | 
    
         
            +
                before { opts['oauth2.client'] = client }
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                context 'and grant_type is invalid' do
         
     | 
| 
      
 15 
     | 
    
         
            +
                  let(:params) { Hash[:grant_type => 'xclient_credentials'] }
         
     | 
| 
      
 16 
     | 
    
         
            +
                  before { opts[:params] = params }
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  it 'responds with invalid_request' do
         
     | 
| 
      
 19 
     | 
    
         
            +
                    do_request
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                    response.status.should eq(400)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    response_object['error'].should eq('invalid_request')
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                context 'and grant_type is valid' do
         
     | 
| 
      
 27 
     | 
    
         
            +
                  let(:params) { Hash[:grant_type => 'client_credentials'] }
         
     | 
| 
      
 28 
     | 
    
         
            +
                  before { opts[:params] = params }
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  context 'and issuer is not specified' do
         
     | 
| 
      
 31 
     | 
    
         
            +
                    it 'responds with unauthorized_client' do
         
     | 
| 
      
 32 
     | 
    
         
            +
                      do_request
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                      response.status.should eq(400)
         
     | 
| 
      
 35 
     | 
    
         
            +
                      response_object['error'].should eq('unauthorized_client')
         
     | 
| 
      
 36 
     | 
    
         
            +
                    end
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  context 'and issuer is specified' do
         
     | 
| 
      
 40 
     | 
    
         
            +
                    let(:issuer) { double('issuer') }
         
     | 
| 
      
 41 
     | 
    
         
            +
                    let(:expected_find_opts) {
         
     | 
| 
      
 42 
     | 
    
         
            +
                      Hash[:grant_type => 'client_credentials',
         
     | 
| 
      
 43 
     | 
    
         
            +
                           :client => client,
         
     | 
| 
      
 44 
     | 
    
         
            +
                           :scope => nil]
         
     | 
| 
      
 45 
     | 
    
         
            +
                    }
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                    app { OAuth2::Rack::Authorization::ClientCredentials::AccessTokenIssuer.new(chained_app) { |opts| issuer.call(opts) } }
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    context 'but token is not found for the client' do
         
     | 
| 
      
 50 
     | 
    
         
            +
                      context 'and error is returned' do
         
     | 
| 
      
 51 
     | 
    
         
            +
                        before {
         
     | 
| 
      
 52 
     | 
    
         
            +
                          issuer.should_receive(:call).with(expected_find_opts).and_return({'error' => 'customized_error'})
         
     | 
| 
      
 53 
     | 
    
         
            +
                        }
         
     | 
| 
      
 54 
     | 
    
         
            +
                        it 'responds with the that error' do
         
     | 
| 
      
 55 
     | 
    
         
            +
                          do_request
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                          response.status.should eq(400)
         
     | 
| 
      
 58 
     | 
    
         
            +
                          response_object['error'].should eq('customized_error')
         
     | 
| 
      
 59 
     | 
    
         
            +
                        end
         
     | 
| 
      
 60 
     | 
    
         
            +
                      end
         
     | 
| 
      
 61 
     | 
    
         
            +
                      context 'and nothing is returned' do
         
     | 
| 
      
 62 
     | 
    
         
            +
                        before {
         
     | 
| 
      
 63 
     | 
    
         
            +
                          issuer.should_receive(:call).with(expected_find_opts).and_return(nil)
         
     | 
| 
      
 64 
     | 
    
         
            +
                        }
         
     | 
| 
      
 65 
     | 
    
         
            +
                        it 'responds with unauthorized_client' do
         
     | 
| 
      
 66 
     | 
    
         
            +
                          do_request
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                          response.status.should eq(400)
         
     | 
| 
      
 69 
     | 
    
         
            +
                          response_object['error'].should eq('unauthorized_client')
         
     | 
| 
      
 70 
     | 
    
         
            +
                        end
         
     | 
| 
      
 71 
     | 
    
         
            +
                      end
         
     | 
| 
      
 72 
     | 
    
         
            +
                      
         
     | 
| 
      
 73 
     | 
    
         
            +
                    end
         
     | 
| 
      
 74 
     | 
    
         
            +
                    context 'and token is found for the client' do
         
     | 
| 
      
 75 
     | 
    
         
            +
                      before {
         
     | 
| 
      
 76 
     | 
    
         
            +
                        issuer.should_receive(:call).with(expected_find_opts).and_return({:access_token => 'X'})
         
     | 
| 
      
 77 
     | 
    
         
            +
                      }
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                      it 'responds with the found token' do
         
     | 
| 
      
 80 
     | 
    
         
            +
                        do_request
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                        response.status.should eq(200)
         
     | 
| 
      
 83 
     | 
    
         
            +
                        response_object['access_token'].should eq('X')
         
     | 
| 
      
 84 
     | 
    
         
            +
                      end
         
     | 
| 
      
 85 
     | 
    
         
            +
                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
                end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
              end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
              context 'when client not authenticated' do
         
     | 
| 
      
 92 
     | 
    
         
            +
                before { post '/' }
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                it 'responds with invalid_client' do
         
     | 
| 
      
 95 
     | 
    
         
            +
                  response.status.should eq(400)
         
     | 
| 
      
 96 
     | 
    
         
            +
                  response_object['error'].should eq('invalid_client')
         
     | 
| 
      
 97 
     | 
    
         
            +
                end
         
     | 
| 
      
 98 
     | 
    
         
            +
              end
         
     | 
| 
      
 99 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,101 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe OAuth2::Rack::Authorization::Password::AccessTokenIssuer do
         
     | 
| 
      
 4 
     | 
    
         
            +
              let(:resource_owner) { double('resource_owner') }
         
     | 
| 
      
 5 
     | 
    
         
            +
              let(:client) { double('client') }
         
     | 
| 
      
 6 
     | 
    
         
            +
              let(:opts) { Hash.new }
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def do_request
         
     | 
| 
      
 9 
     | 
    
         
            +
                post '/', opts
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              context 'when resource_owner is authenticated' do
         
     | 
| 
      
 13 
     | 
    
         
            +
                before { opts['oauth2.resource_owner'] = resource_owner }
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                context 'and grant_type is invalid' do
         
     | 
| 
      
 16 
     | 
    
         
            +
                  let(:params) { Hash[:grant_type => 'xpassword'] }
         
     | 
| 
      
 17 
     | 
    
         
            +
                  before { opts[:params] = params }
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  it 'responds with invalid_request' do
         
     | 
| 
      
 20 
     | 
    
         
            +
                    do_request
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    response.status.should eq(400)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    response_object['error'].should eq('invalid_request')
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                context 'and grant_type is valid' do
         
     | 
| 
      
 28 
     | 
    
         
            +
                  let(:params) { Hash[:grant_type => 'password'] }
         
     | 
| 
      
 29 
     | 
    
         
            +
                  before { opts[:params] = params }
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  context 'and issuer is not specified' do
         
     | 
| 
      
 32 
     | 
    
         
            +
                    it 'responds with unauthorized_client' do
         
     | 
| 
      
 33 
     | 
    
         
            +
                      do_request
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                      response.status.should eq(400)
         
     | 
| 
      
 36 
     | 
    
         
            +
                      response_object['error'].should eq('unauthorized_client')
         
     | 
| 
      
 37 
     | 
    
         
            +
                    end
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  context 'and issuer is specified' do
         
     | 
| 
      
 41 
     | 
    
         
            +
                    let(:issuer) { double('issuer') }
         
     | 
| 
      
 42 
     | 
    
         
            +
                    let(:expected_find_opts) {
         
     | 
| 
      
 43 
     | 
    
         
            +
                      Hash[:grant_type => 'password',
         
     | 
| 
      
 44 
     | 
    
         
            +
                           :resource_owner => resource_owner,
         
     | 
| 
      
 45 
     | 
    
         
            +
                           :client => nil,
         
     | 
| 
      
 46 
     | 
    
         
            +
                           :scope => nil]
         
     | 
| 
      
 47 
     | 
    
         
            +
                    }
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    app { OAuth2::Rack::Authorization::Password::AccessTokenIssuer.new(chained_app) { |opts| issuer.call(opts) } }
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                    context 'but token is not found for the resource owner' do
         
     | 
| 
      
 52 
     | 
    
         
            +
                      context 'and error is returned' do
         
     | 
| 
      
 53 
     | 
    
         
            +
                        before {
         
     | 
| 
      
 54 
     | 
    
         
            +
                          issuer.should_receive(:call).with(expected_find_opts).and_return({'error' => 'customized_error'})
         
     | 
| 
      
 55 
     | 
    
         
            +
                        }
         
     | 
| 
      
 56 
     | 
    
         
            +
                        it 'responds with the that error' do
         
     | 
| 
      
 57 
     | 
    
         
            +
                          do_request
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                          response.status.should eq(400)
         
     | 
| 
      
 60 
     | 
    
         
            +
                          response_object['error'].should eq('customized_error')
         
     | 
| 
      
 61 
     | 
    
         
            +
                        end
         
     | 
| 
      
 62 
     | 
    
         
            +
                      end
         
     | 
| 
      
 63 
     | 
    
         
            +
                      context 'and nothing is returned' do
         
     | 
| 
      
 64 
     | 
    
         
            +
                        before {
         
     | 
| 
      
 65 
     | 
    
         
            +
                          issuer.should_receive(:call).with(expected_find_opts).and_return(nil)
         
     | 
| 
      
 66 
     | 
    
         
            +
                        }
         
     | 
| 
      
 67 
     | 
    
         
            +
                        it 'responds with unauthorized_client' do
         
     | 
| 
      
 68 
     | 
    
         
            +
                          do_request
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                          response.status.should eq(400)
         
     | 
| 
      
 71 
     | 
    
         
            +
                          response_object['error'].should eq('unauthorized_client')
         
     | 
| 
      
 72 
     | 
    
         
            +
                        end
         
     | 
| 
      
 73 
     | 
    
         
            +
                      end
         
     | 
| 
      
 74 
     | 
    
         
            +
                      
         
     | 
| 
      
 75 
     | 
    
         
            +
                    end
         
     | 
| 
      
 76 
     | 
    
         
            +
                    context 'and token is found for the client' do
         
     | 
| 
      
 77 
     | 
    
         
            +
                      before {
         
     | 
| 
      
 78 
     | 
    
         
            +
                        issuer.should_receive(:call).with(expected_find_opts).and_return({:access_token => 'X'})
         
     | 
| 
      
 79 
     | 
    
         
            +
                      }
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                      it 'responds with the found token' do
         
     | 
| 
      
 82 
     | 
    
         
            +
                        do_request
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                        response.status.should eq(200)
         
     | 
| 
      
 85 
     | 
    
         
            +
                        response_object['access_token'].should eq('X')
         
     | 
| 
      
 86 
     | 
    
         
            +
                      end
         
     | 
| 
      
 87 
     | 
    
         
            +
                    end
         
     | 
| 
      
 88 
     | 
    
         
            +
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
              end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
              context 'when resource owner not authenticated' do
         
     | 
| 
      
 94 
     | 
    
         
            +
                before { post '/' }
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                it 'responds with invalid_grant' do
         
     | 
| 
      
 97 
     | 
    
         
            +
                  response.status.should eq(400)
         
     | 
| 
      
 98 
     | 
    
         
            +
                  response_object['error'].should eq('invalid_grant')
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
              end
         
     | 
| 
      
 101 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | 
         @@ -0,0 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            $: << File.expand_path('../../lib', __FILE__)
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'oauth2/rack'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'multi_json'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            # Requires supporting ruby files with custom matchers and macros, etc,
         
     | 
| 
      
 6 
     | 
    
         
            +
            # in spec/support/ and its subdirectories.
         
     | 
| 
      
 7 
     | 
    
         
            +
            Dir[File.expand_path("../support/**/*.rb", __FILE__)].each {|f| require f}
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            RSpec.configure do |config|
         
     | 
| 
      
 10 
     | 
    
         
            +
              config.mock_with :rspec
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,97 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rack/mock'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rack/utils'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module RackTestHelper
         
     | 
| 
      
 5 
     | 
    
         
            +
              def self.included(klass)
         
     | 
| 
      
 6 
     | 
    
         
            +
                klass.extend ClassMethods
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              attr_accessor :response
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def chained_app
         
     | 
| 
      
 12 
     | 
    
         
            +
                if defined?(@original_chained_app)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @original_chained_app
         
     | 
| 
      
 14 
     | 
    
         
            +
                else
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @original_chained_app = instance_eval(&self.class.chained_app)
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
              
         
     | 
| 
      
 19 
     | 
    
         
            +
              def app
         
     | 
| 
      
 20 
     | 
    
         
            +
                if defined?(@original_app)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @original_app
         
     | 
| 
      
 22 
     | 
    
         
            +
                else
         
     | 
| 
      
 23 
     | 
    
         
            +
                  @original_app = instance_eval(&self.class.app)
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              def request
         
     | 
| 
      
 28 
     | 
    
         
            +
                @request ||= Rack::MockRequest.new(app)
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              def response_object
         
     | 
| 
      
 32 
     | 
    
         
            +
                return unless response
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                case response['Content-Type']
         
     | 
| 
      
 35 
     | 
    
         
            +
                when %r{^application/json}
         
     | 
| 
      
 36 
     | 
    
         
            +
                  MultiJson::decode(response.body)
         
     | 
| 
      
 37 
     | 
    
         
            +
                when %r{^application/x-www-form-urlencoded}
         
     | 
| 
      
 38 
     | 
    
         
            +
                  Rack::Utils.new.parse(response.body)
         
     | 
| 
      
 39 
     | 
    
         
            +
                else
         
     | 
| 
      
 40 
     | 
    
         
            +
                  response.body
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
              def get(uri, opts = {})
         
     | 
| 
      
 45 
     | 
    
         
            +
                self.response = request.get(uri, opts)
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
              def post(uri, opts = {})
         
     | 
| 
      
 48 
     | 
    
         
            +
                self.response = request.post(uri, opts)
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
              def put(uri, opts = {})
         
     | 
| 
      
 51 
     | 
    
         
            +
                self.response = request.put(uri, opts)
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
              def delete(uri, opts = {})
         
     | 
| 
      
 54 
     | 
    
         
            +
                self.response = request.delete(uri, opts)
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
              module ClassMethods
         
     | 
| 
      
 58 
     | 
    
         
            +
                attr_reader :explicit_chained_app_block
         
     | 
| 
      
 59 
     | 
    
         
            +
                def chained_app(&block)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  block ? @explicit_chained_app_block = block : explicit_chained_app || implicit_chained_app
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                attr_reader :explicit_app_block
         
     | 
| 
      
 64 
     | 
    
         
            +
                def app(&block)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  block ? @explicit_app_block = block : explicit_app || implicit_app
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                def explicit_app
         
     | 
| 
      
 69 
     | 
    
         
            +
                  group = self
         
     | 
| 
      
 70 
     | 
    
         
            +
                  while group.respond_to?(:explicit_app_block)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    return group.explicit_app_block if group.explicit_app_block
         
     | 
| 
      
 72 
     | 
    
         
            +
                    group = group.superclass
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
                end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                def implicit_app
         
     | 
| 
      
 77 
     | 
    
         
            +
                  described = describes || description
         
     | 
| 
      
 78 
     | 
    
         
            +
                  Class === described ? proc { described.new(chained_app) } : proc { described }
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                def explicit_chained_app
         
     | 
| 
      
 82 
     | 
    
         
            +
                  group = self
         
     | 
| 
      
 83 
     | 
    
         
            +
                  while group.respond_to?(:explicit_chained_app_block)
         
     | 
| 
      
 84 
     | 
    
         
            +
                    return group.explicit_chained_app_block if group.explicit_chained_app_block
         
     | 
| 
      
 85 
     | 
    
         
            +
                    group = group.superclass
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
                end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                def implicit_chained_app
         
     | 
| 
      
 90 
     | 
    
         
            +
                  proc { |env| [200, {"Content-Type" => 'text/html'}, ["<p>OK</p>"]] }
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
              end
         
     | 
| 
      
 93 
     | 
    
         
            +
            end
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            RSpec.configure do |config|
         
     | 
| 
      
 96 
     | 
    
         
            +
              config.include RackTestHelper
         
     | 
| 
      
 97 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,167 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: oauth2-rack
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.0.1
         
     | 
| 
      
 5 
     | 
    
         
            +
              prerelease: 
         
     | 
| 
      
 6 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 7 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 8 
     | 
    
         
            +
            - Ian Yang
         
     | 
| 
      
 9 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 10 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 11 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2011-08-26 00:00:00.000000000Z
         
     | 
| 
      
 13 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 14 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 15 
     | 
    
         
            +
              name: multi_json
         
     | 
| 
      
 16 
     | 
    
         
            +
              requirement: &8610000 !ruby/object:Gem::Requirement
         
     | 
| 
      
 17 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 18 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 19 
     | 
    
         
            +
                - - ! '>='
         
     | 
| 
      
 20 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 21 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 22 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 23 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 24 
     | 
    
         
            +
              version_requirements: *8610000
         
     | 
| 
      
 25 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 26 
     | 
    
         
            +
              name: rack
         
     | 
| 
      
 27 
     | 
    
         
            +
              requirement: &8609580 !ruby/object:Gem::Requirement
         
     | 
| 
      
 28 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 29 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 30 
     | 
    
         
            +
                - - ! '>='
         
     | 
| 
      
 31 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 32 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 33 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 34 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 35 
     | 
    
         
            +
              version_requirements: *8609580
         
     | 
| 
      
 36 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 37 
     | 
    
         
            +
              name: rake
         
     | 
| 
      
 38 
     | 
    
         
            +
              requirement: &8609160 !ruby/object:Gem::Requirement
         
     | 
| 
      
 39 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 40 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 41 
     | 
    
         
            +
                - - ! '>='
         
     | 
| 
      
 42 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 43 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 44 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 45 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 46 
     | 
    
         
            +
              version_requirements: *8609160
         
     | 
| 
      
 47 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 48 
     | 
    
         
            +
              name: rspec
         
     | 
| 
      
 49 
     | 
    
         
            +
              requirement: &8608740 !ruby/object:Gem::Requirement
         
     | 
| 
      
 50 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 51 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 52 
     | 
    
         
            +
                - - ! '>='
         
     | 
| 
      
 53 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 54 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 55 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 56 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 57 
     | 
    
         
            +
              version_requirements: *8608740
         
     | 
| 
      
 58 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 59 
     | 
    
         
            +
              name: yard
         
     | 
| 
      
 60 
     | 
    
         
            +
              requirement: &8608320 !ruby/object:Gem::Requirement
         
     | 
| 
      
 61 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 62 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 63 
     | 
    
         
            +
                - - ! '>='
         
     | 
| 
      
 64 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 65 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 66 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 67 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 68 
     | 
    
         
            +
              version_requirements: *8608320
         
     | 
| 
      
 69 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 70 
     | 
    
         
            +
              name: shotgun
         
     | 
| 
      
 71 
     | 
    
         
            +
              requirement: &8607900 !ruby/object:Gem::Requirement
         
     | 
| 
      
 72 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 73 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 74 
     | 
    
         
            +
                - - ! '>='
         
     | 
| 
      
 75 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 76 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 77 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 78 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 79 
     | 
    
         
            +
              version_requirements: *8607900
         
     | 
| 
      
 80 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 81 
     | 
    
         
            +
              name: guard-rspec
         
     | 
| 
      
 82 
     | 
    
         
            +
              requirement: &8607480 !ruby/object:Gem::Requirement
         
     | 
| 
      
 83 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 84 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 85 
     | 
    
         
            +
                - - ! '>='
         
     | 
| 
      
 86 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 87 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 88 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 89 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 90 
     | 
    
         
            +
              version_requirements: *8607480
         
     | 
| 
      
 91 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 92 
     | 
    
         
            +
              name: oauth2
         
     | 
| 
      
 93 
     | 
    
         
            +
              requirement: &8607060 !ruby/object:Gem::Requirement
         
     | 
| 
      
 94 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 95 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 96 
     | 
    
         
            +
                - - ! '>='
         
     | 
| 
      
 97 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 98 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 99 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 100 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 101 
     | 
    
         
            +
              version_requirements: *8607060
         
     | 
| 
      
 102 
     | 
    
         
            +
            description: Rack middlewares for OAuth2 authorization server and resource server
         
     | 
| 
      
 103 
     | 
    
         
            +
            email:
         
     | 
| 
      
 104 
     | 
    
         
            +
            - me@iany.me
         
     | 
| 
      
 105 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 106 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 107 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 108 
     | 
    
         
            +
            files:
         
     | 
| 
      
 109 
     | 
    
         
            +
            - .gitignore
         
     | 
| 
      
 110 
     | 
    
         
            +
            - .rspec
         
     | 
| 
      
 111 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 112 
     | 
    
         
            +
            - Guardfile
         
     | 
| 
      
 113 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 114 
     | 
    
         
            +
            - config.ru
         
     | 
| 
      
 115 
     | 
    
         
            +
            - examples/ruby-client/password_authorization.rb
         
     | 
| 
      
 116 
     | 
    
         
            +
            - lib/oauth2-rack.rb
         
     | 
| 
      
 117 
     | 
    
         
            +
            - lib/oauth2/rack.rb
         
     | 
| 
      
 118 
     | 
    
         
            +
            - lib/oauth2/rack/authentication.rb
         
     | 
| 
      
 119 
     | 
    
         
            +
            - lib/oauth2/rack/authentication/client.rb
         
     | 
| 
      
 120 
     | 
    
         
            +
            - lib/oauth2/rack/authentication/client/http_basic.rb
         
     | 
| 
      
 121 
     | 
    
         
            +
            - lib/oauth2/rack/authentication/client/request_params.rb
         
     | 
| 
      
 122 
     | 
    
         
            +
            - lib/oauth2/rack/authentication/resource_owner.rb
         
     | 
| 
      
 123 
     | 
    
         
            +
            - lib/oauth2/rack/authentication/resource_owner/request_params.rb
         
     | 
| 
      
 124 
     | 
    
         
            +
            - lib/oauth2/rack/authorization.rb
         
     | 
| 
      
 125 
     | 
    
         
            +
            - lib/oauth2/rack/authorization/client_credentials.rb
         
     | 
| 
      
 126 
     | 
    
         
            +
            - lib/oauth2/rack/authorization/client_credentials/access_token_issuer.rb
         
     | 
| 
      
 127 
     | 
    
         
            +
            - lib/oauth2/rack/authorization/password.rb
         
     | 
| 
      
 128 
     | 
    
         
            +
            - lib/oauth2/rack/authorization/password/access_token_issuer.rb
         
     | 
| 
      
 129 
     | 
    
         
            +
            - spec/oauth2/rack/authentication/client/http_basic_spec.rb
         
     | 
| 
      
 130 
     | 
    
         
            +
            - spec/oauth2/rack/authentication/client/request_params_spec.rb
         
     | 
| 
      
 131 
     | 
    
         
            +
            - spec/oauth2/rack/authentication/resource_owner/request_params_spec.rb
         
     | 
| 
      
 132 
     | 
    
         
            +
            - spec/oauth2/rack/authorization/client_credentials/access_token_issuer_spec.rb
         
     | 
| 
      
 133 
     | 
    
         
            +
            - spec/oauth2/rack/authorization/password/access_token_issuer_spec.rb
         
     | 
| 
      
 134 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     | 
| 
      
 135 
     | 
    
         
            +
            - spec/support/rake_test_helper.rb
         
     | 
| 
      
 136 
     | 
    
         
            +
            homepage: https://github.com/doitian/oauth2-rack
         
     | 
| 
      
 137 
     | 
    
         
            +
            licenses: []
         
     | 
| 
      
 138 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 139 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 140 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 141 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 142 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 143 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 144 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 145 
     | 
    
         
            +
              - - ! '>='
         
     | 
| 
      
 146 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 147 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 148 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 149 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 150 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 151 
     | 
    
         
            +
              - - ! '>='
         
     | 
| 
      
 152 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 153 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 154 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 155 
     | 
    
         
            +
            rubyforge_project: oauth2-rack
         
     | 
| 
      
 156 
     | 
    
         
            +
            rubygems_version: 1.8.6
         
     | 
| 
      
 157 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 158 
     | 
    
         
            +
            specification_version: 3
         
     | 
| 
      
 159 
     | 
    
         
            +
            summary: Rack middlewares for OAuth2 authorization server and resource server
         
     | 
| 
      
 160 
     | 
    
         
            +
            test_files:
         
     | 
| 
      
 161 
     | 
    
         
            +
            - spec/oauth2/rack/authentication/client/http_basic_spec.rb
         
     | 
| 
      
 162 
     | 
    
         
            +
            - spec/oauth2/rack/authentication/client/request_params_spec.rb
         
     | 
| 
      
 163 
     | 
    
         
            +
            - spec/oauth2/rack/authentication/resource_owner/request_params_spec.rb
         
     | 
| 
      
 164 
     | 
    
         
            +
            - spec/oauth2/rack/authorization/client_credentials/access_token_issuer_spec.rb
         
     | 
| 
      
 165 
     | 
    
         
            +
            - spec/oauth2/rack/authorization/password/access_token_issuer_spec.rb
         
     | 
| 
      
 166 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     | 
| 
      
 167 
     | 
    
         
            +
            - spec/support/rake_test_helper.rb
         
     |