summary refs log tree commit
diff options
context:
space:
mode:
authorScytrin dai Kinthra <scytrin@gmail.com>2009-11-22 15:45:20 -0800
committerScytrin dai Kinthra <scytrin@gmail.com>2009-11-22 17:44:10 -0800
commit1a5d7356e3c256d28d9675bcfde39184bbd0c554 (patch)
tree84b14097980a95a220e14abc02a0f6a7703e004b
parent5db5d4e7432d026a7bddf344f97e8facd09128d8 (diff)
downloadrack-1a5d7356e3c256d28d9675bcfde39184bbd0c554.tar.gz
Initial removal of OpenID related files
Removal of references in Rakefile and the core include
-rw-r--r--Rakefile3
-rw-r--r--lib/rack.rb1
-rw-r--r--lib/rack/auth/openid.rb487
-rw-r--r--test/spec_rack_auth_openid.rb84
4 files changed, 1 insertions, 574 deletions
diff --git a/Rakefile b/Rakefile
index c88f7aff..2da515ff 100644
--- a/Rakefile
+++ b/Rakefile
@@ -86,7 +86,7 @@ end
 
 desc "Run all the fast tests"
 task :test do
-  sh "specrb -Ilib:test -w #{ENV['TEST'] || '-a'} #{ENV['TESTOPTS'] || '-t "^(?!Rack::Handler|Rack::Adapter|Rack::Session::Memcache|Rack::Auth::OpenID)"'}"
+  sh "specrb -Ilib:test -w #{ENV['TEST'] || '-a'} #{ENV['TESTOPTS'] || '-t "^(?!Rack::Handler|Rack::Adapter|Rack::Session::Memcache)"'}"
 end
 
 desc "Run all the tests"
@@ -135,7 +135,6 @@ Also see http://rack.rubyforge.org.
       s.add_development_dependency 'fcgi'
       s.add_development_dependency 'memcache-client'
       s.add_development_dependency 'mongrel'
-      s.add_development_dependency 'ruby-openid', '~> 2.0.0'
       s.add_development_dependency 'thin'
     end
 
diff --git a/lib/rack.rb b/lib/rack.rb
index 703649cd..25438afe 100644
--- a/lib/rack.rb
+++ b/lib/rack.rb
@@ -59,7 +59,6 @@ module Rack
     autoload :Basic, "rack/auth/basic"
     autoload :AbstractRequest, "rack/auth/abstract/request"
     autoload :AbstractHandler, "rack/auth/abstract/handler"
-    autoload :OpenID, "rack/auth/openid"
     module Digest
       autoload :MD5, "rack/auth/digest/md5"
       autoload :Nonce, "rack/auth/digest/nonce"
diff --git a/lib/rack/auth/openid.rb b/lib/rack/auth/openid.rb
deleted file mode 100644
index 43cbe4f9..00000000
--- a/lib/rack/auth/openid.rb
+++ /dev/null
@@ -1,487 +0,0 @@
-# AUTHOR: Scytrin dai Kinthra <scytrin@gmail.com>; blink#ruby-lang@irc.freenode.net
-
-gem 'ruby-openid', '~> 2' if defined? Gem
-require 'rack/request'
-require 'rack/utils'
-require 'rack/auth/abstract/handler'
-
-require 'uri'
-require 'openid'
-require 'openid/extension'
-require 'openid/store/memory'
-
-module Rack
-  class Request
-    def openid_request
-      @env['rack.auth.openid.request']
-    end
-
-    def openid_response
-      @env['rack.auth.openid.response']
-    end
-  end
-
-  module Auth
-
-    # Rack::Auth::OpenID provides a simple method for setting up an OpenID
-    # Consumer. It requires the ruby-openid library from janrain to operate,
-    # as well as a rack method of session management.
-    #
-    # The ruby-openid home page is at http://openidenabled.com/ruby-openid/.
-    #
-    # The OpenID specifications can be found at
-    # http://openid.net/specs/openid-authentication-1_1.html
-    # and
-    # http://openid.net/specs/openid-authentication-2_0.html. Documentation
-    # for published OpenID extensions and related topics can be found at
-    # http://openid.net/developers/specs/.
-    #
-    # It is recommended to read through the OpenID spec, as well as
-    # ruby-openid's documentation, to understand what exactly goes on. However
-    # a setup as simple as the presented examples is enough to provide
-    # Consumer functionality.
-    #
-    # This library strongly intends to utilize the OpenID 2.0 features of the
-    # ruby-openid library, which provides OpenID 1.0 compatiblity.
-    #
-    # NOTE: Due to the amount of data that this library stores in the
-    # session, Rack::Session::Cookie may fault.
-    #
-    # == Examples
-    #
-    #   simple_oid = OpenID.new('http://mysite.com/')
-    #
-    #   return_oid = OpenID.new('http://mysite.com/', {
-    #     :return_to => 'http://mysite.com/openid'
-    #   })
-    #
-    #   complex_oid = OpenID.new('http://mysite.com/',
-    #     :immediate => true,
-    #     :extensions => {
-    #       ::OpenID::SReg => [['email'],['nickname']]
-    #     }
-    #   )
-    #
-    # = Advanced
-    #
-    # Most of the functionality of this library is encapsulated such that
-    # expansion and overriding functions isn't difficult nor tricky.
-    # Alternately, to avoid opening up singleton objects or subclassing, a
-    # wrapper rack middleware can be composed to act upon Auth::OpenID's
-    # responses. See #check and #finish for locations of pertinent data.
-    #
-    # == Responses
-    #
-    # To change the responses that Auth::OpenID returns, override the methods
-    # #redirect, #bad_request, #unauthorized, #access_denied, and
-    # #foreign_server_failure.
-    #
-    # Additionally #confirm_post_params is used when the URI would exceed
-    # length limits on a GET request when doing the initial verification
-    # request.
-    #
-    # == Processing
-    #
-    # To change methods of processing completed transactions, override the
-    # methods #success, #setup_needed, #cancel, and #failure. Please ensure
-    # the returned object is a rack compatible response.
-    #
-    # The first argument is an OpenID::Response, the second is a
-    # Rack::Request of the current request, the last is the hash used in
-    # ruby-openid handling, which can be found manually at
-    # env['rack.session'][:openid].
-    #
-    # This is useful if you wanted to expand the processing done, such as
-    # setting up user accounts.
-    #
-    #   oid_app = Rack::Auth::OpenID.new realm, :return_to => return_to
-    #   def oid_app.success oid, request, session
-    #     user = Models::User[oid.identity_url]
-    #     user ||= Models::User.create_from_openid oid
-    #     request['rack.session'][:user] = user.id
-    #     redirect MyApp.site_home
-    #   end
-    #
-    #   site_map['/openid'] = oid_app
-    #   map = Rack::URLMap.new site_map
-    #   ...
-
-    class OpenID
-      # Raised if an incompatible session is being used.
-      class NoSession < RuntimeError; end
-      # Raised if an extension not matching specifications is provided.
-      class BadExtension < RuntimeError; end
-      # Possible statuses returned from consumer responses. See definitions
-      # in the ruby-openid library.
-      ValidStatus = [
-        ::OpenID::Consumer::SUCCESS,
-        ::OpenID::Consumer::FAILURE,
-        ::OpenID::Consumer::CANCEL,
-        ::OpenID::Consumer::SETUP_NEEDED
-      ]
-
-      # The first argument is the realm, identifying the site they are trusting
-      # with their identity. This is required, also treated as the trust_root
-      # in OpenID 1.x exchanges.
-      #
-      # The lits of acceptable options include :return_to, :session_key,
-      # :openid_param, :store, :immediate, :extensions.
-      #
-      # <tt>:return_to</tt> defines the url to return to after the client
-      # authenticates with the openid service provider. This url should point
-      # to where Rack::Auth::OpenID is mounted. If unprovided, the url of
-      # the current request is used.
-      #
-      # <tt>:session_key</tt> defines the key to the session hash in the env.
-      # The default is 'rack.session'.
-      #
-      # <tt>:openid_param</tt> defines at what key in the request parameters to
-      # find the identifier to resolve. As per the 2.0 spec, the default is
-      # 'openid_identifier'.
-      #
-      # <tt>:store</tt> defined what OpenID Store to use for persistant
-      # information. By default a Store::Memory is used.
-      #
-      # <tt>:immediate</tt> as true will make initial requests to be of an
-      # immediate type. This is false by default. See OpenID specification
-      # documentation.
-      #
-      # <tt>:extensions</tt> should be a hash of openid extension
-      # implementations. The key should be the extension module, the value
-      # should be an array of arguments for extension::Request.new().
-      # The hash is iterated over and passed to #add_extension for processing.
-      # Please see #add_extension for further documentation.
-
-      def initialize(realm, options={})
-        realm = URI(realm)
-        raise ArgumentError, "Invalid realm: #{realm}" \
-          unless realm.absolute? \
-          and realm.fragment.nil? \
-          and realm.scheme =~ /^https?$/ \
-          and realm.host =~ /^(\*\.)?#{URI::REGEXP::PATTERN::URIC_NO_SLASH}+/
-        realm.path = '/' if realm.path.empty?
-        @realm = realm.to_s
-
-        if ruri = options[:return_to]
-          ruri = URI(ruri)
-          raise ArgumentError, "Invalid return_to: #{ruri}" \
-            unless ruri.absolute? \
-            and ruri.scheme =~ /^https?$/ \
-            and ruri.fragment.nil?
-          raise ArgumentError, "return_to #{ruri} not within realm #{realm}" \
-            unless self.within_realm?(ruri)
-          @return_to = ruri.to_s
-        end
-
-        @session_key  = options[:session_key]   || 'rack.session'
-        @openid_param = options[:openid_param]  || 'openid_identifier'
-        @store        = options[:store]         || ::OpenID::Store::Memory.new
-        @immediate    = !!options[:immediate]
-
-        @extensions   = {}
-        if extensions = options[:extensions]
-          extensions.each do |ext, args|
-            add_extension(ext, *args)
-          end
-        end
-
-        # Undocumented, semi-experimental
-        @anonymous    = !!options[:anonymous]
-      end
-
-      attr_reader :realm, :return_to, :session_key, :openid_param, :store,
-        :immediate, :extensions
-
-      # Sets up and uses session data at <tt>:openid</tt> within the session.
-      # Errors in this setup will raise a NoSession exception.
-      #
-      # If the parameter 'openid.mode' is set, which implies a followup from
-      # the openid server, processing is passed to #finish and the result is
-      # returned. However, if there is no appropriate openid information in the
-      # session, a 400 error is returned.
-      #
-      # If the parameter specified by <tt>options[:openid_param]</tt> is
-      # present, processing is passed to #check and the result is returned.
-      #
-      # If neither of these conditions are met, #bad_request is called.
-
-      def call(env)
-        env['rack.auth.openid'] = self
-        env_session = env[@session_key]
-        unless env_session and env_session.is_a?(Hash)
-          raise NoSession, 'No compatible session.'
-        end
-        # let us work in our own namespace...
-        session = (env_session[:openid] ||= {})
-        unless session and session.is_a?(Hash)
-          raise NoSession, 'Incompatible openid session.'
-        end
-
-        request = Rack::Request.new(env)
-        consumer = ::OpenID::Consumer.new(session, @store)
-
-        if mode = request.GET['openid.mode']
-          finish(consumer, session, request)
-        elsif request.GET[@openid_param]
-          check(consumer, session, request)
-        else
-          bad_request
-        end
-      end
-
-      # As the first part of OpenID consumer action, #check retrieves the data
-      # required for completion.
-      #
-      # If all parameters fit within the max length of a URI, a 303 redirect
-      # will be returned. Otherwise #confirm_post_params will be called.
-      #
-      # Any messages from OpenID's request are logged to env['rack.errors']
-      #
-      # <tt>env['rack.auth.openid.request']</tt> is the openid checkid request
-      # instance.
-      #
-      # <tt>session[:openid_param]</tt> is set to the openid identifier
-      # provided by the user.
-      #
-      # <tt>session[:return_to]</tt> is set to the return_to uri given to the
-      # identity provider.
-
-      def check(consumer, session, req)
-        oid = consumer.begin(req.GET[@openid_param], @anonymous)
-        req.env['rack.auth.openid.request'] = oid
-        req.env['rack.errors'].puts(oid.message)
-        p oid if $DEBUG
-
-        ## Extension support
-        extensions.each do |ext,args|
-          oid.add_extension(ext::Request.new(*args))
-        end
-
-        session[:openid_param] = req.GET[openid_param]
-        return_to_uri = return_to ? return_to : req.url
-        session[:return_to] = return_to_uri
-        immediate = session.key?(:setup_needed) ? false : immediate
-
-        if oid.send_redirect?(realm, return_to_uri, immediate)
-          redirect(oid.redirect_url(realm, return_to_uri, immediate))
-        else
-          confirm_post_params(oid, realm, return_to_uri, immediate)
-        end
-      rescue ::OpenID::DiscoveryFailure => e
-        # thrown from inside OpenID::Consumer#begin by yadis stuff
-        req.env['rack.errors'].puts( [e.message, *e.backtrace]*"\n" )
-        return foreign_server_failure
-      end
-
-      # This is the final portion of authentication.
-      # If successful, a redirect to the realm is be returned.
-      # Data gathered from extensions are stored in session[:openid] with the
-      # extension's namespace uri as the key.
-      #
-      # Any messages from OpenID's response are logged to env['rack.errors']
-      #
-      # <tt>env['rack.auth.openid.response']</tt> will contain the openid
-      # response.
-
-      def finish(consumer, session, req)
-        oid = consumer.complete(req.GET, req.url)
-        req.env['rack.auth.openid.response'] = oid
-        req.env['rack.errors'].puts(oid.message)
-        p oid if $DEBUG
-
-        if ValidStatus.include?(oid.status)
-          __send__(oid.status, oid, req, session)
-        else
-          invalid_status(oid, req, session)
-        end
-      end
-
-      # The first argument should be the main extension module.
-      # The extension module should contain the constants:
-      # * class Request, should have OpenID::Extension as an ancestor
-      # * class Response, should have OpenID::Extension as an ancestor
-      # * string NS_URI, which defining the namespace of the extension
-      #
-      # All trailing arguments will be passed to extension::Request.new in
-      # #check.
-      # The openid response will be passed to
-      # extension::Response#from_success_response, oid#get_extension_args will
-      # be called on the result to attain the gathered data.
-      #
-      # This method returns the key at which the response data will be found in
-      # the session, which is the namespace uri by default.
-
-      def add_extension(ext, *args)
-        raise BadExtension unless valid_extension?(ext)
-        extensions[ext] = args
-        return ext::NS_URI
-      end
-
-      # Checks the validitity, in the context of usage, of a submitted
-      # extension.
-
-      def valid_extension?(ext)
-        if not %w[NS_URI Request Response].all?{|c| ext.const_defined?(c) }
-          raise ArgumentError, 'Extension is missing constants.'
-        elsif not ext::Response.respond_to?(:from_success_response)
-          raise ArgumentError, 'Response is missing required method.'
-        end
-        return true
-      rescue
-        return false
-      end
-
-      # Checks the provided uri to ensure it'd be considered within the realm.
-      # is currently not compatible with wildcard realms.
-
-      def within_realm? uri
-        uri = URI.parse(uri.to_s)
-        realm = URI.parse(self.realm)
-        return false unless uri.absolute?
-        return false unless uri.path[0, realm.path.size] == realm.path
-        return false unless uri.host == realm.host or realm.host[/^\*\./]
-        # for wildcard support, is awkward with URI limitations
-        realm_match = Regexp.escape(realm.host).
-          sub(/^\*\./,"^#{URI::REGEXP::PATTERN::URIC_NO_SLASH}+.")+'$'
-        return false unless uri.host.match(realm_match)
-        return true
-      end
-
-      alias_method :include?, :within_realm?
-
-      protected
-
-      # Returns an html form page for posting to an Identity Provider if the
-      # GET request would exceed the upper URI length limit.
-
-      def confirm_post_params(oid, realm, return_to, immediate)
-        response = Rack::Response.new '<html>'+
-          '<head><title>Confirm...</title></head>'+
-          '<body>'+oid.form_markup(realm, return_to, immediate)+'</body>'+
-          '</html>'
-        response.finish
-      end
-
-      # Returns a 303 redirect with the destination of that provided by the
-      # argument.
-
-      def redirect(uri)
-        [ 303, {'Content-Type'=>'text/plain', 'Content-Length'=>'0',
-          'Location' => uri},
-          [] ]
-      end
-
-      # Returns an empty 400 response.
-
-      def bad_request
-        [ 400, {'Content-Type'=>'text/plain', 'Content-Length'=>'0'},
-          [''] ]
-      end
-
-      # Returns a basic unauthorized 401 response.
-
-      def unauthorized
-        [ 401, {'Content-Type' => 'text/plain', 'Content-Length' => '13'},
-          ['Unauthorized.'] ]
-      end
-
-      # Returns a basic access denied 403 response.
-
-      def access_denied
-        [ 403, {'Content-Type' => 'text/plain', 'Content-Length' => '14'},
-          ['Access denied.'] ]
-      end
-
-      # Returns a 503 response to be used if communication with the remote
-      # OpenID server fails.
-
-      def foreign_server_failure
-        [ 503, {'Content-Type'=>'text/plain', 'Content-Length' => '23'},
-          ['Foreign server failure.'] ]
-      end
-
-      private
-
-      # Called to complete processing on a successful transaction.
-      # Within the openid session, :openid_identity and :openid_identifier are
-      # set to the user friendly and the standard representation of the
-      # validated identity. All other data in the openid session is cleared.
-
-      def success(oid, request, session)
-        session.clear
-        session[:openid_identity]   = oid.display_identifier
-        session[:openid_identifier] = oid.identity_url
-        extensions.keys.each do |ext|
-          label     = ext.name[/[^:]+$/].downcase
-          response  = ext::Response.from_success_response(oid)
-          session[label] = response.data
-        end
-        redirect(realm)
-      end
-
-      # Called if the Identity Provider indicates further setup by the user is
-      # required.
-      # The identifier is retrived from the openid session at :openid_param.
-      # And :setup_needed is set to true to prevent looping.
-
-      def setup_needed(oid, request, session)
-        identifier = session[:openid_param]
-        session[:setup_needed] = true
-        redirect(req.script_name + '?' + openid_param + '=' + identifier)
-      end
-
-      # Called if the user indicates they wish to cancel identification.
-      # Data within openid session is cleared.
-
-      def cancel(oid, request, session)
-        session.clear
-        access_denied
-      end
-
-      # Called if the Identity Provider indicates the user is unable to confirm
-      # their identity. Data within the openid session is left alone, in case
-      # of swarm auth attacks.
-
-      def failure(oid, request, session)
-        unauthorized
-      end
-
-      # To be called if there is no method for handling the OpenID response
-      # status.
-
-      def invalid_status(oid, request, session)
-        msg = 'Invalid status returned by the OpenID authorization reponse.'
-        [ 500,
-          {'Content-Type'=>'text/plain','Content-Length'=>msg.length.to_s},
-          [msg] ]
-      end
-    end
-
-    # A class developed out of the request to use OpenID as an authentication
-    # middleware. The request will be sent to the OpenID instance unless the
-    # block evaluates to true. For example in rackup, you can use it as such:
-    #
-    #   use Rack::Session::Pool
-    #   use Rack::Auth::OpenIDAuth, realm, openid_options do |env|
-    #     env['rack.session'][:authkey] == a_string
-    #   end
-    #   run RackApp
-    #
-    # Or simply:
-    #
-    #   app = Rack::Auth::OpenIDAuth.new app, realm, openid_options, &auth
-
-    class OpenIDAuth < Rack::Auth::AbstractHandler
-      attr_reader :oid
-      def initialize(app, realm, options={}, &auth)
-        @oid = OpenID.new(realm, options)
-        super(app, &auth)
-      end
-
-      def call(env)
-        to = @authenticator.call(env) ? @app : @oid
-        to.call(env)
-      end
-    end
-  end
-end
diff --git a/test/spec_rack_auth_openid.rb b/test/spec_rack_auth_openid.rb
deleted file mode 100644
index ba248445..00000000
--- a/test/spec_rack_auth_openid.rb
+++ /dev/null
@@ -1,84 +0,0 @@
-require 'test/spec'
-
-begin
-# requires the ruby-openid gem
-require 'rack/auth/openid'
-
-context "Rack::Auth::OpenID" do
-  OID = Rack::Auth::OpenID
-  host = 'host'
-  subd = 'sub.host'
-  wild = '*.host'
-  path = 'path'
-  long = 'path/long'
-  scheme = 'http://'
-  realm = scheme+host+'/'+path
-
-  specify 'realm uri should be valid' do
-    lambda{OID.new('/'+path)}.should.raise ArgumentError
-    lambda{OID.new('/'+long)}.should.raise ArgumentError
-    lambda{OID.new(scheme+host)}.should.not.raise
-    lambda{OID.new(scheme+host+'/')}.should.not.raise
-    lambda{OID.new(scheme+host+'/'+path)}.should.not.raise
-    lambda{OID.new(scheme+subd)}.should.not.raise
-    lambda{OID.new(scheme+subd+'/')}.should.not.raise
-    lambda{OID.new(scheme+subd+'/'+path)}.should.not.raise
-  end
-
-  specify 'should be able to check if a uri is within the realm' do
-  end
-
-  specify 'return_to should be valid' do
-    uri = '/'+path
-    lambda{OID.new(realm, :return_to=>uri)}.should.raise ArgumentError
-    uri = '/'+long
-    lambda{OID.new(realm, :return_to=>uri)}.should.raise ArgumentError
-    uri = scheme+host
-    lambda{OID.new(realm, :return_to=>uri)}.should.raise ArgumentError
-    uri = scheme+host+'/'+path
-    lambda{OID.new(realm, :return_to=>uri)}.should.not.raise
-    uri = scheme+subd+'/'+path
-    lambda{OID.new(realm, :return_to=>uri)}.should.raise ArgumentError
-    uri = scheme+host+'/'+long
-    lambda{OID.new(realm, :return_to=>uri)}.should.not.raise
-    uri = scheme+subd+'/'+long
-    lambda{OID.new(realm, :return_to=>uri)}.should.raise ArgumentError
-  end
-
-  specify 'extensions should have required constants defined' do
-    badext = Rack::Auth::OpenID::BadExtension
-    ext = Object.new
-    lambda{OID.new(realm).add_extension(ext)}.should.raise(badext)
-    ext = Module.new
-    lambda{OID.new(realm).add_extension(ext)}.should.raise(badext)
-    ext::Request = nil
-    lambda{OID.new(realm).add_extension(ext)}.should.raise(badext)
-    ext::Response = nil
-    lambda{OID.new(realm).add_extension(ext)}.should.raise(badext)
-    ext::NS_URI = nil
-    lambda{OID.new(realm).add_extension(ext)}.should.raise(badext)
-  end
-
-  specify 'extensions should have Request and Response defined and inherit from OpenID::Extension' do
-    $-w, w = nil, $-w               # yuck
-    badext = Rack::Auth::OpenID::BadExtension
-    ext = Module.new
-    ext::Request = nil
-    ext::Response = nil
-    ext::NS_URI = nil
-    lambda{OID.new(realm).add_extension(ext)}.should.raise(badext)
-    ext::Request = Class.new()
-    lambda{OID.new(realm).add_extension(ext)}.should.raise(badext)
-    ext::Response = Class.new()
-    lambda{OID.new(realm).add_extension(ext)}.should.raise(badext)
-    ext::Request = Class.new(::OpenID::Extension)
-    lambda{OID.new(realm).add_extension(ext)}.should.raise(badext)
-    ext::Response = Class.new(::OpenID::Extension)
-    lambda{OID.new(realm).add_extension(ext)}.should.raise(badext)
-    $-w = w
-  end
-end
-
-rescue LoadError
-  $stderr.puts "Skipping Rack::Auth::OpenID tests (ruby-openid 2 is required). `gem install ruby-openid` and try again."
-end