class OpenID::Message

Attributes

namespaces[R]

Public Class Methods

from_http_response(response, server_url) click to toggle source
# File lib/openid/kvpost.rb, line 31
def self.from_http_response(response, server_url)
  msg = self.from_kvform(response.body)
  case response.code.to_i
  when 200
    return msg
  when 206
    return msg
  when 400
    raise ServerError.from_message(msg)
  else
    error_message = "bad status code from server #{server_url}: "         "#{response.code}"
    raise HTTPStatusError.new(error_message)
  end
end
from_kvform(kvform_string) click to toggle source

Create a message from a KVForm string

# File lib/openid/message.rb, line 217
def Message.from_kvform(kvform_string)
  return Message.from_openid_args(Util.kv_to_dict(kvform_string))
end
from_openid_args(openid_args) click to toggle source

Construct a Message from a parsed KVForm message. Raises InvalidNamespaceError if you try to instantiate a Message with a namespace not in the above allowed list

# File lib/openid/message.rb, line 139
def Message.from_openid_args(openid_args)
  m = Message.new
  m._from_openid_args(openid_args)
  return m
end
from_post_args(args) click to toggle source

Construct a Message containing a set of POST arguments. Raises InvalidNamespaceError if you try to instantiate a Message with a namespace not in the above allowed list

# File lib/openid/message.rb, line 114
def Message.from_post_args(args)
  m = Message.new
  openid_args = {}
  args.each do |key,value|
    if value.is_a?(Array)
      raise ArgumentError, "Query dict must have one value for each key, " +
        "not lists of values.  Query is #{args.inspect}"
    end

    prefix, rest = key.split('.', 2)

    if prefix != 'openid' or rest.nil?
      m.set_arg(BARE_NS, key, value)
    else
      openid_args[rest] = value
    end
  end

  m._from_openid_args(openid_args)
  return m
end
new(openid_namespace=nil) click to toggle source

Raises InvalidNamespaceError if you try to instantiate a Message with a namespace not in the above allowed list

# File lib/openid/message.rb, line 100
def initialize(openid_namespace=nil)
  @args = {}
  @namespaces = NamespaceMap.new
  if openid_namespace
    implicit = OPENID1_NAMESPACES.member? openid_namespace
    self.set_openid_namespace(openid_namespace, implicit)
  else
    @openid_ns_uri = nil
  end
end
register_namespace_alias(namespace_uri, alias_) click to toggle source

Registers a (namespace URI, alias) mapping in a global namespace alias map. Raises NamespaceAliasRegistrationError if either the namespace URI or alias has already been registered with a different value. This function is required if you want to use a namespace with an OpenID 1 message.

# File lib/openid/message.rb, line 78
def Message.register_namespace_alias(namespace_uri, alias_)
  if @@registered_aliases[alias_] == namespace_uri
      return
  end

  if @@registered_aliases.values.include?(namespace_uri)
    raise NamespaceAliasRegistrationError,
      'Namespace uri #{namespace_uri} already registered'
  end

  if @@registered_aliases.member?(alias_)
    raise NamespaceAliasRegistrationError,
      'Alias #{alias_} already registered'
  end

  @@registered_aliases[alias_] = namespace_uri
end

Public Instance Methods

==(other) click to toggle source
# File lib/openid/message.rb, line 420
def ==(other)
  other.is_a?(self.class) && @args == other.instance_eval { @args }
end
_fix_ns(namespace) click to toggle source

Convert an input value into the internally used values of this obejct.

# File lib/openid/message.rb, line 318
def _fix_ns(namespace)
  if namespace == OPENID_NS
    unless @openid_ns_uri
      raise UndefinedOpenIDNamespace, 'OpenID namespace not set'
    else
      namespace = @openid_ns_uri
    end
  end

  if namespace == BARE_NS
    return namespace
  end

  if !namespace.is_a?(String)
    raise ArgumentError, ("Namespace must be BARE_NS, OPENID_NS or "                               "a string. Got #{namespace.inspect}")
  end

  if namespace.index(':').nil?
    msg = ("OpenID 2.0 namespace identifiers SHOULD be URIs. "                "Got #{namespace.inspect}")
    Util.log(msg)

    if namespace == 'sreg'
      msg = "Using #{SREG_URI} instead of \"sreg\" as namespace"
      Util.log(msg)
      return SREG_URI
    end
  end

  return namespace
end
_from_openid_args(openid_args) click to toggle source

Raises InvalidNamespaceError if you try to instantiate a Message with a namespace not in the above allowed list

# File lib/openid/message.rb, line 147
def _from_openid_args(openid_args)
  ns_args = []

  # resolve namespaces
  openid_args.each { |rest, value|
    ns_alias, ns_key = rest.split('.', 2)
    if ns_key.nil?
      ns_alias = NULL_NAMESPACE
      ns_key = rest
    end

    if ns_alias == 'ns'
      @namespaces.add_alias(value, ns_key)
    elsif ns_alias == NULL_NAMESPACE and ns_key == 'ns'
      set_openid_namespace(value, false)
    else
      ns_args << [ns_alias, ns_key, value]
    end
  }

  # implicitly set an OpenID 1 namespace
  unless get_openid_namespace
    set_openid_namespace(OPENID1_NS, true)
  end

  # put the pairs into the appropriate namespaces
  ns_args.each { |ns_alias, ns_key, value|
    ns_uri = @namespaces.get_namespace_uri(ns_alias)
    unless ns_uri
      ns_uri = _get_default_namespace(ns_alias)
      unless ns_uri
        ns_uri = get_openid_namespace
        ns_key = "#{ns_alias}.#{ns_key}"
      else
        @namespaces.add_alias(ns_uri, ns_alias, true)
      end
    end
    self.set_arg(ns_uri, ns_key, value)
  }
end
_get_default_namespace(mystery_alias) click to toggle source
# File lib/openid/message.rb, line 188
def _get_default_namespace(mystery_alias)
  # only try to map an alias to a default if it's an
  # OpenID 1.x namespace
  if is_openid1
    @@registered_aliases[mystery_alias]
  end
end
copy() click to toggle source
# File lib/openid/message.rb, line 221
def copy
  return Marshal.load(Marshal.dump(self))
end
del_arg(namespace, key) click to toggle source

Remove a single argument from this namespace.

# File lib/openid/message.rb, line 414
def del_arg(namespace, key)
  namespace = _fix_ns(namespace)
  _key = [namespace, key]
  @args.delete(_key)
end
get_aliased_arg(aliased_key, default=nil) click to toggle source
# File lib/openid/message.rb, line 424
def get_aliased_arg(aliased_key, default=nil)
  if aliased_key == 'ns'
    return get_openid_namespace()
  end

  ns_alias, key = aliased_key.split('.', 2)
  if ns_alias == 'ns'
    uri = @namespaces.get_namespace_uri(key)
    if uri.nil? and default == NO_DEFAULT
      raise KeyNotFound, "Namespace #{key} not defined when looking "                              "for #{aliased_key}"
    else
      return (uri.nil? ? default : uri)
    end
  end

  if key.nil?
    key = aliased_key
    ns = nil
  else
    ns = @namespaces.get_namespace_uri(ns_alias)
  end

  if ns.nil?
    key = aliased_key
    ns = get_openid_namespace
  end

  return get_arg(ns, key, default)
end
get_arg(namespace, key, default=nil) click to toggle source

Get a value for a namespaced key.

# File lib/openid/message.rb, line 376
def get_arg(namespace, key, default=nil)
  namespace = _fix_ns(namespace)
  @args.fetch([namespace, key]) {
    if default == NO_DEFAULT
      raise KeyNotFound, "<#{namespace}>#{key} not in this message"
    else
      default
    end
  }
end
get_args(namespace) click to toggle source

Get the arguments that are defined for this namespace URI.

# File lib/openid/message.rb, line 388
def get_args(namespace)
  namespace = _fix_ns(namespace)
  args = {}
  @args.each { |k,v|
    pair_ns, ns_key = k
    args[ns_key] = v if pair_ns == namespace
  }
  return args
end
get_key(namespace, ns_key) click to toggle source

Get the key for a particular namespaced argument

# File lib/openid/message.rb, line 357
def get_key(namespace, ns_key)
  namespace = _fix_ns(namespace)
  return ns_key if namespace == BARE_NS

  ns_alias = @namespaces.get_alias(namespace)

  # no alias is defined, so no key can exist
  return nil if ns_alias.nil?

  if ns_alias == NULL_NAMESPACE
    tail = ns_key
  else
    tail = "#{ns_alias}.#{ns_key}"
  end

  return 'openid.' + tail
end
get_openid_namespace() click to toggle source
# File lib/openid/message.rb, line 204
def get_openid_namespace
  return @openid_ns_uri
end
has_key?(namespace, ns_key) click to toggle source
# File lib/openid/message.rb, line 351
def has_key?(namespace, ns_key)
  namespace = _fix_ns(namespace)
  return @args.member?([namespace, ns_key])
end
is_openid1() click to toggle source
# File lib/openid/message.rb, line 208
def is_openid1
  return OPENID1_NAMESPACES.member?(@openid_ns_uri)
end
is_openid2() click to toggle source
# File lib/openid/message.rb, line 212
def is_openid2
  return @openid_ns_uri == OPENID2_NS
end
set_arg(namespace, key, value) click to toggle source

Set a single argument in this namespace

# File lib/openid/message.rb, line 405
def set_arg(namespace, key, value)
  namespace = _fix_ns(namespace)
  @args[[namespace, key].freeze] = value
  if namespace != BARE_NS
    @namespaces.add(namespace)
  end
end
set_openid_namespace(openid_ns_uri, implicit) click to toggle source
# File lib/openid/message.rb, line 196
def set_openid_namespace(openid_ns_uri, implicit)
  if !@@allowed_openid_namespaces.include?(openid_ns_uri)
    raise InvalidOpenIDNamespace, "Invalid null namespace: #{openid_ns_uri}"
  end
  @namespaces.add_alias(openid_ns_uri, NULL_NAMESPACE, implicit)
  @openid_ns_uri = openid_ns_uri
end
to_args() click to toggle source

Return all namespaced arguments, failing if any non-namespaced arguments exist.

# File lib/openid/message.rb, line 253
def to_args
  post_args = self.to_post_args
  kvargs = {}
  post_args.each { |k,v|
    if !k.start_with?('openid.')
      raise ArgumentError, "This message can only be encoded as a POST, because it contains arguments that are not prefixed with 'openid.'"
    else
      kvargs[k[7..-1]] = v
    end
  }
  return kvargs
end
to_form_markup(action_url, form_tag_attrs=nil, submit_text='Continue') click to toggle source

Generate HTML form markup that contains the values in this message, to be HTTP POSTed as x-www-form-urlencoded UTF-8.

# File lib/openid/message.rb, line 268
def to_form_markup(action_url, form_tag_attrs=nil, submit_text='Continue')
  form_tag_attr_map = {}

  if form_tag_attrs
    form_tag_attrs.each { |name, attr|
      form_tag_attr_map[name] = attr
    }
  end

  form_tag_attr_map['action'] = action_url
  form_tag_attr_map['method'] = 'post'
  form_tag_attr_map['accept-charset'] = 'UTF-8'
  form_tag_attr_map['enctype'] = 'application/x-www-form-urlencoded'

  markup = "<form "

  form_tag_attr_map.each { |k, v|
    markup += " #{k}=\"#{v}\""
  }

  markup += ">\n"

  to_post_args.each { |k,v|
    markup += "<input type='hidden' name='#{k}' value='#{OpenID::Util.html_encode(v)}' />\n"
  }
  markup += "<input type='submit' value='#{submit_text}' />\n"
  markup += "\n</form>"
  return markup
end
to_kvform() click to toggle source

Generate a KVForm string that contains the parameters in this message. This will fail is the message contains arguments outside of the “openid.” prefix.

# File lib/openid/message.rb, line 307
def to_kvform
  return Util.dict_to_kv(to_args)
end
to_post_args() click to toggle source

Return all arguments with “openid.” in from of namespaced arguments.

# File lib/openid/message.rb, line 226
def to_post_args
  args = {}

  # add namespace defs to the output
  @namespaces.each { |ns_uri, ns_alias|
    if @namespaces.implicit?(ns_uri)
      next
    end
    if ns_alias == NULL_NAMESPACE
      ns_key = 'openid.ns'
    else
      ns_key = 'openid.ns.' + ns_alias
    end
    args[ns_key] = ns_uri
  }

  @args.each { |k, value|
    ns_uri, ns_key = k
    key = get_key(ns_uri, ns_key)
    args[key] = value
  }

  return args
end
to_url(base_url) click to toggle source

Generate a GET URL with the paramters in this message attacked as query parameters.

# File lib/openid/message.rb, line 300
def to_url(base_url)
  return Util.append_args(base_url, self.to_post_args)
end
to_url_encoded() click to toggle source

Generate an x-www-urlencoded string.

# File lib/openid/message.rb, line 312
def to_url_encoded
  args = to_post_args.map.sort
  return Util.urlencode(args)
end
update_args(namespace, updates) click to toggle source

Set multiple key/value pairs in one call.

# File lib/openid/message.rb, line 399
def update_args(namespace, updates)
  namespace = _fix_ns(namespace)
  updates.each {|k,v| set_arg(namespace, k, v)}
end