Class: OpenID::Server::CheckIDRequest

### Home Classes Methods

### In Files

- lib/openid/server.rb

### Parent

OpenID::Server::OpenIDRequest

### Methods

- ::from_message
- ::new
- #answer
- #cancel_url
- #encode_to_url
- #id_select
- #return_to_verified
- #to_s
- #trust_root_valid

### Files

- LICENSE

### Class/Module Index

Quicksearch

- OpenID
- OpenID::AX
- OpenID::AX::AXMessage
- OpenID::AX::AttrInfo
- OpenID::AX::Error
- OpenID::AX::FetchRequest
- OpenID::AX::FetchResponse
- OpenID::AX::KeyValueMessage
- OpenID::AX::StoreRequest
- OpenID::AX::StoreResponse
- OpenID::AssertionError
- OpenID::Association
- OpenID::AssociationNegotiator
- OpenID::Consumer
- OpenID::Consumer::AssociationManager
- OpenID::Consumer::CancelResponse
- OpenID::Consumer::CheckIDRequest
- OpenID::Consumer::DiffieHellmanSHA1Session
- OpenID::Consumer::DiffieHellmanSHA256Session
- OpenID::Consumer::DiffieHellmanSession
- OpenID::Consumer::DiscoveredServices
- OpenID::Consumer::DiscoveryManager
- OpenID::Consumer::FailureResponse
- OpenID::Consumer::IdResHandler
- OpenID::Consumer::NoEncryptionSession
- OpenID::Consumer::Response
- OpenID::Consumer::Session
- OpenID::Consumer::SetupNeededResponse
- OpenID::Consumer::SuccessResponse
- OpenID::CryptUtil
- OpenID::DiffieHellman
- OpenID::DiscoveryFailure
- OpenID::Extension
- OpenID::FetchingError
- OpenID::HTTPRedirectLimitReached
- OpenID::HTTPResponse
- OpenID::HTTPStatusError
- OpenID::InvalidOpenIDNamespace
- OpenID::KVFormError
- OpenID::KVPostNetworkError
- OpenID::Message
- OpenID::Message::KeyNotFound
- OpenID::NamespaceAliasRegistrationError
- OpenID::NamespaceMap
- OpenID::Nonce
- OpenID::OAuth
- OpenID::OAuth::Request
- OpenID::OAuth::Response
- OpenID::OpenIDError
- OpenID::OpenIDServiceEndpoint
- OpenID::PAPE
- OpenID::PAPE::Request
- OpenID::PAPE::Response
- OpenID::ProtocolError
- OpenID::RealmVerificationRedirected
- OpenID::SReg
- OpenID::SReg::NamespaceError
- OpenID::SReg::Request
- OpenID::SReg::Response
- OpenID::SSLFetchingError
- OpenID::Server
- OpenID::Server::AlreadySigned
- OpenID::Server::AssociateRequest
- OpenID::Server::BaseServerSession
- OpenID::Server::CheckAuthRequest
- OpenID::Server::CheckIDRequest
- OpenID::Server::Decoder
- OpenID::Server::DiffieHellmanSHA1ServerSession
- OpenID::Server::DiffieHellmanSHA256ServerSession
- OpenID::Server::Encoder
- OpenID::Server::EncodingError
- OpenID::Server::MalformedReturnURL
- OpenID::Server::MalformedTrustRoot
- OpenID::Server::NoReturnToError
- OpenID::Server::OpenIDRequest
- OpenID::Server::OpenIDResponse
- OpenID::Server::PlainTextServerSession
- OpenID::Server::ProtocolError
- OpenID::Server::Server
- OpenID::Server::Signatory
- OpenID::Server::SigningEncoder
- OpenID::Server::UntrustedReturnURL
- OpenID::Server::VersionError
- OpenID::Server::WebResponse
- OpenID::ServerError
- OpenID::StandardFetcher
- OpenID::Store
- OpenID::Store::Filesystem
- OpenID::Store::Interface
- OpenID::Store::Memcache
- OpenID::Store::Memory
- OpenID::TrustRoot
- OpenID::TrustRoot::TrustRoot
- OpenID::TypeURIMismatch
- OpenID::UI
- OpenID::UI::Request
- OpenID::URINorm
- OpenID::UndefinedOpenIDNamespace
- OpenID::Util
- OpenID::Yadis
- OpenID::Yadis::BasicServiceEndpoint
- OpenID::Yadis::CompoundFilter
- OpenID::Yadis::DiscoveryResult
- OpenID::Yadis::TransformFilterMaker
- OpenID::Yadis::XRDSError
- OpenID::Yadis::XRDSFraud
- OpenID::Yadis::XRI
- OpenID::Yadis::XRI::ProxyResolver
- OpenID::Yadis::XRI::XRIHTTPError
- HMAC
- HMAC::Base
- HMAC::SHA1
- HMAC::SHA256
- HMAC::SHA384
- HMAC::SHA512
- Net
- Net::HTTP
- HTMLComment
- HTMLTag
- HTMLText
- HTMLToken
- HTMLTokenizer
- HTMLTokenizerError
- Object

No matching classes.

# OpenID::Server::CheckIDRequest

A request to confirm the identity of a user.

This class handles requests for openid modes `checkid_immediate` and `checkid_setup` .

### Attributes

assoc_handle[RW]

Provided in smart mode requests, a handle for a previously established association. nil for dumb mode requests.

claimed_id[RW]

The claimed identifier. Not present in OpenID 1.x messages.

identity[RW]

The OP-local identifier being checked.

immediate[RW]

Is this an immediate-mode request?

mode[RW]

mode | `checkid_immediate` or `checkid_setup`

op_endpoint[RW]
return_to[RW]

The URL to send the user agent back to to reply to this request.

trust_root[RW]

This URL identifies the party making the request, and the user will use that to make her decision about what answer she trusts them to have. Referred to as "realm" in OpenID 2.0.

### Public Class Methods

from_message(message, op_endpoint) click to toggle source

Construct me from an OpenID message.

message | An OpenID checkid_* request Message
op_endpoint | The endpoint URL of the server that this message was sent to.

Raises:

ProtocolError | When not all required parameters are present in the message.
MalformedReturnURL | When the `return_to` URL is not a URL.
UntrustedReturnURL | When the `return_to` URL is outside the `trust_root`.

    # File lib/openid/server.rb, line 490
    def self.from_message(message, op_endpoint)
      obj = self.allocate
      obj.message = message
      obj.op_endpoint = op_endpoint
      mode = message.get_arg(OPENID_NS, 'mode')
      if mode == "checkid_immediate"
        obj.immediate = true
        obj.mode = "checkid_immediate"
      else
        obj.immediate = false
        obj.mode = "checkid_setup"
      end

      obj.return_to = message.get_arg(OPENID_NS, 'return_to')
      if message.is_openid1 and !obj.return_to
        msg = sprintf("Missing required field 'return_to' from %s",
                      message)
        raise ProtocolError.new(message, msg)
      end

      obj.identity = message.get_arg(OPENID_NS, 'identity')
      obj.claimed_id = message.get_arg(OPENID_NS, 'claimed_id')
      if message.is_openid1()
        if !obj.identity
          s = "OpenID 1 message did not contain openid.identity"
          raise ProtocolError.new(message, s)
        end
      else
        if obj.identity and not obj.claimed_id
          s = ("OpenID 2.0 message contained openid.identity but not " +
               "claimed_id")
          raise ProtocolError.new(message, s)
        elsif obj.claimed_id and not obj.identity
          s = ("OpenID 2.0 message contained openid.claimed_id but not " +
               "identity")
          raise ProtocolError.new(message, s)
        end
      end

      # There's a case for making self.trust_root be a TrustRoot
      # here.  But if TrustRoot isn't currently part of the "public"
      # API, I'm not sure it's worth doing.
      if message.is_openid1
        trust_root_param = 'trust_root'
      else
        trust_root_param = 'realm'
      end
      trust_root = message.get_arg(OPENID_NS, trust_root_param)
      trust_root = obj.return_to if (trust_root.nil? || trust_root.empty?)
      obj.trust_root = trust_root

      if !message.is_openid1 and !obj.return_to and !obj.trust_root
        raise ProtocolError.new(message, "openid.realm required when " +
                                "openid.return_to absent")
      end

      obj.assoc_handle = message.get_arg(OPENID_NS, 'assoc_handle')

      # Using TrustRoot.parse here is a bit misleading, as we're not
      # parsing return_to as a trust root at all.  However, valid
      # URLs are valid trust roots, so we can use this to get an
      # idea if it is a valid URL.  Not all trust roots are valid
      # return_to URLs, however (particularly ones with wildcards),
      # so this is still a little sketchy.
      if obj.return_to and            !TrustRoot::TrustRoot.parse(obj.return_to)
        raise MalformedReturnURL.new(message, obj.return_to)
      end

      # I first thought that checking to see if the return_to is
      # within the trust_root is premature here, a
      # logic-not-decoding thing.  But it was argued that this is
      # really part of data validation.  A request with an invalid
      # trust_root/return_to is broken regardless of application,
      # right?
      if !obj.trust_root_valid()
        raise UntrustedReturnURL.new(message, obj.return_to, obj.trust_root)
      end

      return obj
    end

new(identity, return_to, op_endpoint, trust_root=nil, immediate=false, assoc_handle=nil, claimed_id=nil) click to toggle source

These parameters are assigned directly as attributes, see the #CheckIDRequest class documentation for their descriptions.

Raises #MalformedReturnURL when the `return_to` URL is not a URL.

    # File lib/openid/server.rb, line 447
    def initialize(identity, return_to, op_endpoint, trust_root=nil,
                   immediate=false, assoc_handle=nil, claimed_id=nil)
      @assoc_handle = assoc_handle
      @identity = identity
      @claimed_id = (claimed_id or identity)
      @return_to = return_to
      @trust_root = (trust_root or return_to)
      @op_endpoint = op_endpoint
      @message = nil

      if immediate
        @immediate = true
        @mode = "checkid_immediate"
      else
        @immediate = false
        @mode = "checkid_setup"
      end

      if @return_to and
          !TrustRoot::TrustRoot.parse(@return_to)
        raise MalformedReturnURL.new(nil, @return_to)
      end

      if !trust_root_valid()
        raise UntrustedReturnURL.new(nil, @return_to, @trust_root)
      end
    end

### Public Instance Methods

answer(allow, server_url=nil, identity=nil, claimed_id=nil) click to toggle source

Respond to this request.

allow | Allow this user to claim this identity, and allow the consumer to have this information?
server_url | DEPRECATED. Passing op_endpoint to the #Server constructor makes this optional. When an OpenID 1.x immediate mode request does not succeed, it gets back a URL where the request may be carried out in a not-so-immediate fashion. Pass my URL in here (the fully qualified address of this server's endpoint, i.e. `http://example.com/server`), and I will use it as a base for the URL for a new request. Optional for requests where #CheckIDRequest.immediate is false or `allow` is true.
identity | The OP-local identifier to answer with. Only for use when the relying party requested identifier selection.
claimed_id | The claimed identifier to answer with, for use with identifier selection in the case where the claimed identifier and the OP-local identifier differ, i.e. when the claimed_id uses delegation. If `identity` is provided but this is not, `claimed_id` will default to the value of `identity`. When answering requests that did not ask for identifier selection, the response `claimed_id` will default to that of the request. This parameter is new in OpenID 2.0.

Returns an OpenIDResponse object containing a OpenID id_res message.

Raises NoReturnToError if the return_to is missing.

Version 2.0 deprecates `server_url` and adds `claimed_id`.

    # File lib/openid/server.rb, line 657
    def answer(allow, server_url=nil, identity=nil, claimed_id=nil)
      if !@return_to
        raise NoReturnToError
      end

      if !server_url
        if @message.is_openid2 and !@op_endpoint
          # In other words, that warning I raised in
          # Server.__init__?  You should pay attention to it now.
          raise RuntimeError, ("#{self} should be constructed with "                                  "op_endpoint to respond to OpenID 2.0 "                                  "messages.")
        end

        server_url = @op_endpoint
      end

      if allow
        mode = 'id_res'
      elsif @message.is_openid1
        if @immediate
          mode = 'id_res'
        else
          mode = 'cancel'
        end
      else
        if @immediate
          mode = 'setup_needed'
        else
          mode = 'cancel'
        end
      end

      response = OpenIDResponse.new(self)

      if claimed_id and @message.is_openid1
        raise VersionError, ("claimed_id is new in OpenID 2.0 and not "                                "available for #{@message.get_openid_namespace}")
      end

      if identity and !claimed_id
        claimed_id = identity
      end

      if allow
        if @identity == IDENTIFIER_SELECT
          if !identity
            raise ArgumentError, ("This request uses IdP-driven "                                     "identifier selection.You must supply "                                     "an identifier in the response.")
          end

          response_identity = identity
          response_claimed_id = claimed_id

        elsif @identity
          if identity and (@identity != identity)
            raise ArgumentError, ("Request was for identity #{@identity}, "                                     "cannot reply with identity #{identity}")
          end

          response_identity = @identity
          response_claimed_id = @claimed_id
        else
          if identity
            raise ArgumentError, ("This request specified no identity "                                     "and you supplied #{identity}")
          end
          response_identity = nil
        end

        if @message.is_openid1 and !response_identity
          raise ArgumentError, ("Request was an OpenID 1 request, so "                                   "response must include an identifier.")
        end

        response.fields.update_args(OPENID_NS, {
              'mode' => mode,
              'op_endpoint' => server_url,
              'return_to' => @return_to,
              'response_nonce' => Nonce.mk_nonce(),
              })

        if response_identity
          response.fields.set_arg(OPENID_NS, 'identity', response_identity)
          if @message.is_openid2
            response.fields.set_arg(OPENID_NS,
                                    'claimed_id', response_claimed_id)
          end
        end
      else
        response.fields.set_arg(OPENID_NS, 'mode', mode)
        if @immediate
          if @message.is_openid1 and !server_url
            raise ArgumentError, ("setup_url is required for allow=false "                                     "in OpenID 1.x immediate mode.")
          end

          # Make a new request just like me, but with
          # immediate=false.
          setup_request = self.class.new(@identity, @return_to,
                                         @op_endpoint, @trust_root, false,
                                         @assoc_handle, @claimed_id)
          setup_request.message = Message.new(@message.get_openid_namespace)
          setup_url = setup_request.encode_to_url(server_url)
          response.fields.set_arg(OPENID_NS, 'user_setup_url', setup_url)
        end
      end

      return response
    end

cancel_url() click to toggle source

    # File lib/openid/server.rb, line 804
    def cancel_url
      # Get the URL to cancel this request.
      #
      # Useful for creating a "Cancel" button on a web form so that
      # operation can be carried out directly without another trip
      # through the server.
      #
      # (Except you may want to make another trip through the
      # server so that it knows that the user did make a decision.)
      #
      # Returns a URL as a string.
      if !@return_to
        raise NoReturnToError
      end

      if @immediate
        raise ArgumentError.new("Cancel is not an appropriate response to " +
                                "immediate mode requests.")
      end

      response = Message.new(@message.get_openid_namespace)
      response.set_arg(OPENID_NS, 'mode', 'cancel')
      return response.to_url(@return_to)
    end

encode_to_url(server_url) click to toggle source

    # File lib/openid/server.rb, line 769
    def encode_to_url(server_url)
      # Encode this request as a URL to GET.
      #
      # server_url:: The URL of the OpenID server to make this
      #              request of.
      if !@return_to
        raise NoReturnToError
      end

      # Imported from the alternate reality where these classes are
      # used in both the client and server code, so Requests are
      # Encodable too.  That's right, code imported from alternate
      # realities all for the love of you, id_res/user_setup_url.
      q = {'mode' => @mode,
           'identity' => @identity,
           'claimed_id' => @claimed_id,
           'return_to' => @return_to}

      if @trust_root
        if @message.is_openid1
          q['trust_root'] = @trust_root
        else
          q['realm'] = @trust_root
        end
      end

      if @assoc_handle
        q['assoc_handle'] = @assoc_handle
      end

      response = Message.new(@message.get_openid_namespace)
      response.update_args(@message.get_openid_namespace, q)
      return response.to_url(server_url)
    end

id_select() click to toggle source

Is the identifier to be selected by the IDP?

    # File lib/openid/server.rb, line 573
    def id_select
      # So IDPs don't have to import the constant
      return @identity == IDENTIFIER_SELECT
    end

return_to_verified() click to toggle source

Does the relying party publish the return_to URL for this response under the realm? It is up to the provider to set a policy for what kinds of realms should be allowed. This return_to URL verification reduces vulnerability to data-theft attacks based on open proxies, corss-site-scripting, or open redirectors.

This check should only be performed after making sure that the return_to URL matches the realm.

Raises DiscoveryFailure if the realm URL does not support Yadis discovery (and so does not support the verification process).

Returns true if the realm publishes a document with the return_to URL listed

    # File lib/openid/server.rb, line 612
    def return_to_verified
      return TrustRoot.verify_return_to(@trust_root, @return_to)
    end

to_s() click to toggle source

    # File lib/openid/server.rb, line 829
    def to_s
      return sprintf('<%s id:%s im:%s tr:%s ah:%s>', self.class,
                     @identity,
                     @immediate,
                     @trust_root,
                     @assoc_handle)
    end

trust_root_valid() click to toggle source

Is my return_to under my trust_root?

    # File lib/openid/server.rb, line 579
    def trust_root_valid
      if !@trust_root
        return true
      end

      tr = TrustRoot::TrustRoot.parse(@trust_root)
      if !tr
        raise MalformedTrustRoot.new(@message, @trust_root)
      end

      if @return_to
        return tr.validate_url(@return_to)
      else
        return true
      end
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.