summaryrefslogtreecommitdiff
path: root/extlib/Auth/OpenID/Message.php
diff options
context:
space:
mode:
Diffstat (limited to 'extlib/Auth/OpenID/Message.php')
-rw-r--r--extlib/Auth/OpenID/Message.php915
1 files changed, 915 insertions, 0 deletions
diff --git a/extlib/Auth/OpenID/Message.php b/extlib/Auth/OpenID/Message.php
new file mode 100644
index 000000000..fd23e67a3
--- /dev/null
+++ b/extlib/Auth/OpenID/Message.php
@@ -0,0 +1,915 @@
+<?php
+
+/**
+ * Extension argument processing code
+ *
+ * @package OpenID
+ */
+
+/**
+ * Import tools needed to deal with messages.
+ */
+require_once 'Auth/OpenID.php';
+require_once 'Auth/OpenID/KVForm.php';
+require_once 'Auth/Yadis/XML.php';
+require_once 'Auth/OpenID/Consumer.php'; // For Auth_OpenID_FailureResponse
+
+// This doesn't REALLY belong here, but where is better?
+define('Auth_OpenID_IDENTIFIER_SELECT',
+ "http://specs.openid.net/auth/2.0/identifier_select");
+
+// URI for Simple Registration extension, the only commonly deployed
+// OpenID 1.x extension, and so a special case
+define('Auth_OpenID_SREG_URI', 'http://openid.net/sreg/1.0');
+
+// The OpenID 1.X namespace URI
+define('Auth_OpenID_OPENID1_NS', 'http://openid.net/signon/1.0');
+define('Auth_OpenID_THE_OTHER_OPENID1_NS', 'http://openid.net/signon/1.1');
+
+function Auth_OpenID_isOpenID1($ns)
+{
+ return ($ns == Auth_OpenID_THE_OTHER_OPENID1_NS) ||
+ ($ns == Auth_OpenID_OPENID1_NS);
+}
+
+// The OpenID 2.0 namespace URI
+define('Auth_OpenID_OPENID2_NS', 'http://specs.openid.net/auth/2.0');
+
+// The namespace consisting of pairs with keys that are prefixed with
+// "openid." but not in another namespace.
+define('Auth_OpenID_NULL_NAMESPACE', 'Null namespace');
+
+// The null namespace, when it is an allowed OpenID namespace
+define('Auth_OpenID_OPENID_NS', 'OpenID namespace');
+
+// The top-level namespace, excluding all pairs with keys that start
+// with "openid."
+define('Auth_OpenID_BARE_NS', 'Bare namespace');
+
+// Sentinel for Message implementation to indicate that getArg should
+// return null instead of returning a default.
+define('Auth_OpenID_NO_DEFAULT', 'NO DEFAULT ALLOWED');
+
+// Limit, in bytes, of identity provider and return_to URLs, including
+// response payload. See OpenID 1.1 specification, Appendix D.
+define('Auth_OpenID_OPENID1_URL_LIMIT', 2047);
+
+// All OpenID protocol fields. Used to check namespace aliases.
+global $Auth_OpenID_OPENID_PROTOCOL_FIELDS;
+$Auth_OpenID_OPENID_PROTOCOL_FIELDS = array(
+ 'ns', 'mode', 'error', 'return_to', 'contact', 'reference',
+ 'signed', 'assoc_type', 'session_type', 'dh_modulus', 'dh_gen',
+ 'dh_consumer_public', 'claimed_id', 'identity', 'realm',
+ 'invalidate_handle', 'op_endpoint', 'response_nonce', 'sig',
+ 'assoc_handle', 'trust_root', 'openid');
+
+// Global namespace / alias registration map. See
+// Auth_OpenID_registerNamespaceAlias.
+global $Auth_OpenID_registered_aliases;
+$Auth_OpenID_registered_aliases = array();
+
+/**
+ * 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.
+ */
+function Auth_OpenID_registerNamespaceAlias($namespace_uri, $alias)
+{
+ global $Auth_OpenID_registered_aliases;
+
+ if (Auth_OpenID::arrayGet($Auth_OpenID_registered_aliases,
+ $alias) == $namespace_uri) {
+ return true;
+ }
+
+ if (in_array($namespace_uri,
+ array_values($Auth_OpenID_registered_aliases))) {
+ return false;
+ }
+
+ if (in_array($alias, array_keys($Auth_OpenID_registered_aliases))) {
+ return false;
+ }
+
+ $Auth_OpenID_registered_aliases[$alias] = $namespace_uri;
+ return true;
+}
+
+/**
+ * Removes a (namespace_uri, alias) registration from the global
+ * namespace alias map. Returns true if the removal succeeded; false
+ * if not (if the mapping did not exist).
+ */
+function Auth_OpenID_removeNamespaceAlias($namespace_uri, $alias)
+{
+ global $Auth_OpenID_registered_aliases;
+
+ if (Auth_OpenID::arrayGet($Auth_OpenID_registered_aliases,
+ $alias) === $namespace_uri) {
+ unset($Auth_OpenID_registered_aliases[$alias]);
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * An Auth_OpenID_Mapping maintains a mapping from arbitrary keys to
+ * arbitrary values. (This is unlike an ordinary PHP array, whose
+ * keys may be only simple scalars.)
+ *
+ * @package OpenID
+ */
+class Auth_OpenID_Mapping {
+ /**
+ * Initialize a mapping. If $classic_array is specified, its keys
+ * and values are used to populate the mapping.
+ */
+ function Auth_OpenID_Mapping($classic_array = null)
+ {
+ $this->keys = array();
+ $this->values = array();
+
+ if (is_array($classic_array)) {
+ foreach ($classic_array as $key => $value) {
+ $this->set($key, $value);
+ }
+ }
+ }
+
+ /**
+ * Returns true if $thing is an Auth_OpenID_Mapping object; false
+ * if not.
+ */
+ function isA($thing)
+ {
+ return (is_object($thing) &&
+ strtolower(get_class($thing)) == 'auth_openid_mapping');
+ }
+
+ /**
+ * Returns an array of the keys in the mapping.
+ */
+ function keys()
+ {
+ return $this->keys;
+ }
+
+ /**
+ * Returns an array of values in the mapping.
+ */
+ function values()
+ {
+ return $this->values;
+ }
+
+ /**
+ * Returns an array of (key, value) pairs in the mapping.
+ */
+ function items()
+ {
+ $temp = array();
+
+ for ($i = 0; $i < count($this->keys); $i++) {
+ $temp[] = array($this->keys[$i],
+ $this->values[$i]);
+ }
+ return $temp;
+ }
+
+ /**
+ * Returns the "length" of the mapping, or the number of keys.
+ */
+ function len()
+ {
+ return count($this->keys);
+ }
+
+ /**
+ * Sets a key-value pair in the mapping. If the key already
+ * exists, its value is replaced with the new value.
+ */
+ function set($key, $value)
+ {
+ $index = array_search($key, $this->keys);
+
+ if ($index !== false) {
+ $this->values[$index] = $value;
+ } else {
+ $this->keys[] = $key;
+ $this->values[] = $value;
+ }
+ }
+
+ /**
+ * Gets a specified value from the mapping, associated with the
+ * specified key. If the key does not exist in the mapping,
+ * $default is returned instead.
+ */
+ function get($key, $default = null)
+ {
+ $index = array_search($key, $this->keys);
+
+ if ($index !== false) {
+ return $this->values[$index];
+ } else {
+ return $default;
+ }
+ }
+
+ /**
+ * @access private
+ */
+ function _reflow()
+ {
+ // PHP is broken yet again. Sort the arrays to remove the
+ // hole in the numeric indexes that make up the array.
+ $old_keys = $this->keys;
+ $old_values = $this->values;
+
+ $this->keys = array();
+ $this->values = array();
+
+ foreach ($old_keys as $k) {
+ $this->keys[] = $k;
+ }
+
+ foreach ($old_values as $v) {
+ $this->values[] = $v;
+ }
+ }
+
+ /**
+ * Deletes a key-value pair from the mapping with the specified
+ * key.
+ */
+ function del($key)
+ {
+ $index = array_search($key, $this->keys);
+
+ if ($index !== false) {
+ unset($this->keys[$index]);
+ unset($this->values[$index]);
+ $this->_reflow();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if the specified value has a key in the mapping;
+ * false if not.
+ */
+ function contains($value)
+ {
+ return (array_search($value, $this->keys) !== false);
+ }
+}
+
+/**
+ * Maintains a bijective map between namespace uris and aliases.
+ *
+ * @package OpenID
+ */
+class Auth_OpenID_NamespaceMap {
+ function Auth_OpenID_NamespaceMap()
+ {
+ $this->alias_to_namespace = new Auth_OpenID_Mapping();
+ $this->namespace_to_alias = new Auth_OpenID_Mapping();
+ $this->implicit_namespaces = array();
+ }
+
+ function getAlias($namespace_uri)
+ {
+ return $this->namespace_to_alias->get($namespace_uri);
+ }
+
+ function getNamespaceURI($alias)
+ {
+ return $this->alias_to_namespace->get($alias);
+ }
+
+ function iterNamespaceURIs()
+ {
+ // Return an iterator over the namespace URIs
+ return $this->namespace_to_alias->keys();
+ }
+
+ function iterAliases()
+ {
+ // Return an iterator over the aliases"""
+ return $this->alias_to_namespace->keys();
+ }
+
+ function iteritems()
+ {
+ return $this->namespace_to_alias->items();
+ }
+
+ function isImplicit($namespace_uri)
+ {
+ return in_array($namespace_uri, $this->implicit_namespaces);
+ }
+
+ function addAlias($namespace_uri, $desired_alias, $implicit=false)
+ {
+ // Add an alias from this namespace URI to the desired alias
+ global $Auth_OpenID_OPENID_PROTOCOL_FIELDS;
+
+ // Check that desired_alias is not an openid protocol field as
+ // per the spec.
+ if (in_array($desired_alias, $Auth_OpenID_OPENID_PROTOCOL_FIELDS)) {
+ Auth_OpenID::log("\"%s\" is not an allowed namespace alias",
+ $desired_alias);
+ return null;
+ }
+
+ // Check that desired_alias does not contain a period as per
+ // the spec.
+ if (strpos($desired_alias, '.') !== false) {
+ Auth_OpenID::log('"%s" must not contain a dot', $desired_alias);
+ return null;
+ }
+
+ // Check that there is not a namespace already defined for the
+ // desired alias
+ $current_namespace_uri =
+ $this->alias_to_namespace->get($desired_alias);
+
+ if (($current_namespace_uri !== null) &&
+ ($current_namespace_uri != $namespace_uri)) {
+ Auth_OpenID::log('Cannot map "%s" because previous mapping exists',
+ $namespace_uri);
+ return null;
+ }
+
+ // Check that there is not already a (different) alias for
+ // this namespace URI
+ $alias = $this->namespace_to_alias->get($namespace_uri);
+
+ if (($alias !== null) && ($alias != $desired_alias)) {
+ Auth_OpenID::log('Cannot map %s to alias %s. ' .
+ 'It is already mapped to alias %s',
+ $namespace_uri, $desired_alias, $alias);
+ return null;
+ }
+
+ assert((Auth_OpenID_NULL_NAMESPACE === $desired_alias) ||
+ is_string($desired_alias));
+
+ $this->alias_to_namespace->set($desired_alias, $namespace_uri);
+ $this->namespace_to_alias->set($namespace_uri, $desired_alias);
+ if ($implicit) {
+ array_push($this->implicit_namespaces, $namespace_uri);
+ }
+
+ return $desired_alias;
+ }
+
+ function add($namespace_uri)
+ {
+ // Add this namespace URI to the mapping, without caring what
+ // alias it ends up with
+
+ // See if this namespace is already mapped to an alias
+ $alias = $this->namespace_to_alias->get($namespace_uri);
+
+ if ($alias !== null) {
+ return $alias;
+ }
+
+ // Fall back to generating a numerical alias
+ $i = 0;
+ while (1) {
+ $alias = 'ext' . strval($i);
+ if ($this->addAlias($namespace_uri, $alias) === null) {
+ $i += 1;
+ } else {
+ return $alias;
+ }
+ }
+
+ // Should NEVER be reached!
+ return null;
+ }
+
+ function contains($namespace_uri)
+ {
+ return $this->isDefined($namespace_uri);
+ }
+
+ function isDefined($namespace_uri)
+ {
+ return $this->namespace_to_alias->contains($namespace_uri);
+ }
+}
+
+/**
+ * In the implementation of this object, null represents the global
+ * namespace as well as a namespace with no key.
+ *
+ * @package OpenID
+ */
+class Auth_OpenID_Message {
+
+ function Auth_OpenID_Message($openid_namespace = null)
+ {
+ // Create an empty Message
+ $this->allowed_openid_namespaces = array(
+ Auth_OpenID_OPENID1_NS,
+ Auth_OpenID_THE_OTHER_OPENID1_NS,
+ Auth_OpenID_OPENID2_NS);
+
+ $this->args = new Auth_OpenID_Mapping();
+ $this->namespaces = new Auth_OpenID_NamespaceMap();
+ if ($openid_namespace === null) {
+ $this->_openid_ns_uri = null;
+ } else {
+ $implicit = Auth_OpenID_isOpenID1($openid_namespace);
+ $this->setOpenIDNamespace($openid_namespace, $implicit);
+ }
+ }
+
+ function isOpenID1()
+ {
+ return Auth_OpenID_isOpenID1($this->getOpenIDNamespace());
+ }
+
+ function isOpenID2()
+ {
+ return $this->getOpenIDNamespace() == Auth_OpenID_OPENID2_NS;
+ }
+
+ function fromPostArgs($args)
+ {
+ // Construct a Message containing a set of POST arguments
+ $obj = new Auth_OpenID_Message();
+
+ // Partition into "openid." args and bare args
+ $openid_args = array();
+ foreach ($args as $key => $value) {
+
+ if (is_array($value)) {
+ return null;
+ }
+
+ $parts = explode('.', $key, 2);
+
+ if (count($parts) == 2) {
+ list($prefix, $rest) = $parts;
+ } else {
+ $prefix = null;
+ }
+
+ if ($prefix != 'openid') {
+ $obj->args->set(array(Auth_OpenID_BARE_NS, $key), $value);
+ } else {
+ $openid_args[$rest] = $value;
+ }
+ }
+
+ if ($obj->_fromOpenIDArgs($openid_args)) {
+ return $obj;
+ } else {
+ return null;
+ }
+ }
+
+ function fromOpenIDArgs($openid_args)
+ {
+ // Takes an array.
+
+ // Construct a Message from a parsed KVForm message
+ $obj = new Auth_OpenID_Message();
+ if ($obj->_fromOpenIDArgs($openid_args)) {
+ return $obj;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * @access private
+ */
+ function _fromOpenIDArgs($openid_args)
+ {
+ global $Auth_OpenID_registered_aliases;
+
+ // Takes an Auth_OpenID_Mapping instance OR an array.
+
+ if (!Auth_OpenID_Mapping::isA($openid_args)) {
+ $openid_args = new Auth_OpenID_Mapping($openid_args);
+ }
+
+ $ns_args = array();
+
+ // Resolve namespaces
+ foreach ($openid_args->items() as $pair) {
+ list($rest, $value) = $pair;
+
+ $parts = explode('.', $rest, 2);
+
+ if (count($parts) == 2) {
+ list($ns_alias, $ns_key) = $parts;
+ } else {
+ $ns_alias = Auth_OpenID_NULL_NAMESPACE;
+ $ns_key = $rest;
+ }
+
+ if ($ns_alias == 'ns') {
+ if ($this->namespaces->addAlias($value, $ns_key) === null) {
+ return false;
+ }
+ } else if (($ns_alias == Auth_OpenID_NULL_NAMESPACE) &&
+ ($ns_key == 'ns')) {
+ // null namespace
+ if ($this->setOpenIDNamespace($value, false) === false) {
+ return false;
+ }
+ } else {
+ $ns_args[] = array($ns_alias, $ns_key, $value);
+ }
+ }
+
+ if (!$this->getOpenIDNamespace()) {
+ if ($this->setOpenIDNamespace(Auth_OpenID_OPENID1_NS, true) ===
+ false) {
+ return false;
+ }
+ }
+
+ // Actually put the pairs into the appropriate namespaces
+ foreach ($ns_args as $triple) {
+ list($ns_alias, $ns_key, $value) = $triple;
+ $ns_uri = $this->namespaces->getNamespaceURI($ns_alias);
+ if ($ns_uri === null) {
+ $ns_uri = $this->_getDefaultNamespace($ns_alias);
+ if ($ns_uri === null) {
+
+ $ns_uri = Auth_OpenID_OPENID_NS;
+ $ns_key = sprintf('%s.%s', $ns_alias, $ns_key);
+ } else {
+ $this->namespaces->addAlias($ns_uri, $ns_alias, true);
+ }
+ }
+
+ $this->setArg($ns_uri, $ns_key, $value);
+ }
+
+ return true;
+ }
+
+ function _getDefaultNamespace($mystery_alias)
+ {
+ global $Auth_OpenID_registered_aliases;
+ if ($this->isOpenID1()) {
+ return @$Auth_OpenID_registered_aliases[$mystery_alias];
+ }
+ return null;
+ }
+
+ function setOpenIDNamespace($openid_ns_uri, $implicit)
+ {
+ if (!in_array($openid_ns_uri, $this->allowed_openid_namespaces)) {
+ Auth_OpenID::log('Invalid null namespace: "%s"', $openid_ns_uri);
+ return false;
+ }
+
+ $succeeded = $this->namespaces->addAlias($openid_ns_uri,
+ Auth_OpenID_NULL_NAMESPACE,
+ $implicit);
+ if ($succeeded === false) {
+ return false;
+ }
+
+ $this->_openid_ns_uri = $openid_ns_uri;
+
+ return true;
+ }
+
+ function getOpenIDNamespace()
+ {
+ return $this->_openid_ns_uri;
+ }
+
+ function fromKVForm($kvform_string)
+ {
+ // Create a Message from a KVForm string
+ return Auth_OpenID_Message::fromOpenIDArgs(
+ Auth_OpenID_KVForm::toArray($kvform_string));
+ }
+
+ function copy()
+ {
+ return $this;
+ }
+
+ function toPostArgs()
+ {
+ // Return all arguments with openid. in front of namespaced
+ // arguments.
+
+ $args = array();
+
+ // Add namespace definitions to the output
+ foreach ($this->namespaces->iteritems() as $pair) {
+ list($ns_uri, $alias) = $pair;
+ if ($this->namespaces->isImplicit($ns_uri)) {
+ continue;
+ }
+ if ($alias == Auth_OpenID_NULL_NAMESPACE) {
+ $ns_key = 'openid.ns';
+ } else {
+ $ns_key = 'openid.ns.' . $alias;
+ }
+ $args[$ns_key] = $ns_uri;
+ }
+
+ foreach ($this->args->items() as $pair) {
+ list($ns_parts, $value) = $pair;
+ list($ns_uri, $ns_key) = $ns_parts;
+ $key = $this->getKey($ns_uri, $ns_key);
+ $args[$key] = $value;
+ }
+
+ return $args;
+ }
+
+ function toArgs()
+ {
+ // Return all namespaced arguments, failing if any
+ // non-namespaced arguments exist.
+ $post_args = $this->toPostArgs();
+ $kvargs = array();
+ foreach ($post_args as $k => $v) {
+ if (strpos($k, 'openid.') !== 0) {
+ // raise ValueError(
+ // 'This message can only be encoded as a POST, because it '
+ // 'contains arguments that are not prefixed with "openid."')
+ return null;
+ } else {
+ $kvargs[substr($k, 7)] = $v;
+ }
+ }
+
+ return $kvargs;
+ }
+
+ function toFormMarkup($action_url, $form_tag_attrs = null,
+ $submit_text = "Continue")
+ {
+ $form = "<form accept-charset=\"UTF-8\" ".
+ "enctype=\"application/x-www-form-urlencoded\"";
+
+ if (!$form_tag_attrs) {
+ $form_tag_attrs = array();
+ }
+
+ $form_tag_attrs['action'] = $action_url;
+ $form_tag_attrs['method'] = 'post';
+
+ unset($form_tag_attrs['enctype']);
+ unset($form_tag_attrs['accept-charset']);
+
+ if ($form_tag_attrs) {
+ foreach ($form_tag_attrs as $name => $attr) {
+ $form .= sprintf(" %s=\"%s\"", $name, $attr);
+ }
+ }
+
+ $form .= ">\n";
+
+ foreach ($this->toPostArgs() as $name => $value) {
+ $form .= sprintf(
+ "<input type=\"hidden\" name=\"%s\" value=\"%s\" />\n",
+ $name, $value);
+ }
+
+ $form .= sprintf("<input type=\"submit\" value=\"%s\" />\n",
+ $submit_text);
+
+ $form .= "</form>\n";
+
+ return $form;
+ }
+
+ function toURL($base_url)
+ {
+ // Generate a GET URL with the parameters in this message
+ // attached as query parameters.
+ return Auth_OpenID::appendArgs($base_url, $this->toPostArgs());
+ }
+
+ function toKVForm()
+ {
+ // Generate a KVForm string that contains the parameters in
+ // this message. This will fail if the message contains
+ // arguments outside of the 'openid.' prefix.
+ return Auth_OpenID_KVForm::fromArray($this->toArgs());
+ }
+
+ function toURLEncoded()
+ {
+ // Generate an x-www-urlencoded string
+ $args = array();
+
+ foreach ($this->toPostArgs() as $k => $v) {
+ $args[] = array($k, $v);
+ }
+
+ sort($args);
+ return Auth_OpenID::httpBuildQuery($args);
+ }
+
+ /**
+ * @access private
+ */
+ function _fixNS($namespace)
+ {
+ // Convert an input value into the internally used values of
+ // this object
+
+ if ($namespace == Auth_OpenID_OPENID_NS) {
+ if ($this->_openid_ns_uri === null) {
+ return new Auth_OpenID_FailureResponse(null,
+ 'OpenID namespace not set');
+ } else {
+ $namespace = $this->_openid_ns_uri;
+ }
+ }
+
+ if (($namespace != Auth_OpenID_BARE_NS) &&
+ (!is_string($namespace))) {
+ //TypeError
+ $err_msg = sprintf("Namespace must be Auth_OpenID_BARE_NS, ".
+ "Auth_OpenID_OPENID_NS or a string. got %s",
+ print_r($namespace, true));
+ return new Auth_OpenID_FailureResponse(null, $err_msg);
+ }
+
+ if (($namespace != Auth_OpenID_BARE_NS) &&
+ (strpos($namespace, ':') === false)) {
+ // fmt = 'OpenID 2.0 namespace identifiers SHOULD be URIs. Got %r'
+ // warnings.warn(fmt % (namespace,), DeprecationWarning)
+
+ if ($namespace == 'sreg') {
+ // fmt = 'Using %r instead of "sreg" as namespace'
+ // warnings.warn(fmt % (SREG_URI,), DeprecationWarning,)
+ return Auth_OpenID_SREG_URI;
+ }
+ }
+
+ return $namespace;
+ }
+
+ function hasKey($namespace, $ns_key)
+ {
+ $namespace = $this->_fixNS($namespace);
+ if (Auth_OpenID::isFailure($namespace)) {
+ // XXX log me
+ return false;
+ } else {
+ return $this->args->contains(array($namespace, $ns_key));
+ }
+ }
+
+ function getKey($namespace, $ns_key)
+ {
+ // Get the key for a particular namespaced argument
+ $namespace = $this->_fixNS($namespace);
+ if (Auth_OpenID::isFailure($namespace)) {
+ return $namespace;
+ }
+ if ($namespace == Auth_OpenID_BARE_NS) {
+ return $ns_key;
+ }
+
+ $ns_alias = $this->namespaces->getAlias($namespace);
+
+ // No alias is defined, so no key can exist
+ if ($ns_alias === null) {
+ return null;
+ }
+
+ if ($ns_alias == Auth_OpenID_NULL_NAMESPACE) {
+ $tail = $ns_key;
+ } else {
+ $tail = sprintf('%s.%s', $ns_alias, $ns_key);
+ }
+
+ return 'openid.' . $tail;
+ }
+
+ function getArg($namespace, $key, $default = null)
+ {
+ // Get a value for a namespaced key.
+ $namespace = $this->_fixNS($namespace);
+
+ if (Auth_OpenID::isFailure($namespace)) {
+ return $namespace;
+ } else {
+ if ((!$this->args->contains(array($namespace, $key))) &&
+ ($default == Auth_OpenID_NO_DEFAULT)) {
+ $err_msg = sprintf("Namespace %s missing required field %s",
+ $namespace, $key);
+ return new Auth_OpenID_FailureResponse(null, $err_msg);
+ } else {
+ return $this->args->get(array($namespace, $key), $default);
+ }
+ }
+ }
+
+ function getArgs($namespace)
+ {
+ // Get the arguments that are defined for this namespace URI
+
+ $namespace = $this->_fixNS($namespace);
+ if (Auth_OpenID::isFailure($namespace)) {
+ return $namespace;
+ } else {
+ $stuff = array();
+ foreach ($this->args->items() as $pair) {
+ list($key, $value) = $pair;
+ list($pair_ns, $ns_key) = $key;
+ if ($pair_ns == $namespace) {
+ $stuff[$ns_key] = $value;
+ }
+ }
+
+ return $stuff;
+ }
+ }
+
+ function updateArgs($namespace, $updates)
+ {
+ // Set multiple key/value pairs in one call
+
+ $namespace = $this->_fixNS($namespace);
+
+ if (Auth_OpenID::isFailure($namespace)) {
+ return $namespace;
+ } else {
+ foreach ($updates as $k => $v) {
+ $this->setArg($namespace, $k, $v);
+ }
+ return true;
+ }
+ }
+
+ function setArg($namespace, $key, $value)
+ {
+ // Set a single argument in this namespace
+ $namespace = $this->_fixNS($namespace);
+
+ if (Auth_OpenID::isFailure($namespace)) {
+ return $namespace;
+ } else {
+ $this->args->set(array($namespace, $key), $value);
+ if ($namespace !== Auth_OpenID_BARE_NS) {
+ $this->namespaces->add($namespace);
+ }
+ return true;
+ }
+ }
+
+ function delArg($namespace, $key)
+ {
+ $namespace = $this->_fixNS($namespace);
+
+ if (Auth_OpenID::isFailure($namespace)) {
+ return $namespace;
+ } else {
+ return $this->args->del(array($namespace, $key));
+ }
+ }
+
+ function getAliasedArg($aliased_key, $default = null)
+ {
+ $parts = explode('.', $aliased_key, 2);
+
+ if (count($parts) != 2) {
+ $ns = null;
+ } else {
+ list($alias, $key) = $parts;
+
+ if ($alias == 'ns') {
+ // Return the namespace URI for a namespace alias
+ // parameter.
+ return $this->namespaces->getNamespaceURI($key);
+ } else {
+ $ns = $this->namespaces->getNamespaceURI($alias);
+ }
+ }
+
+ if ($ns === null) {
+ $key = $aliased_key;
+ $ns = $this->getOpenIDNamespace();
+ }
+
+ return $this->getArg($ns, $key, $default);
+ }
+}
+
+?>