[ Index ]

PHP Cross Reference of Joomla 1.5.26 DE

title

Body

[close]

/libraries/openid/Auth/OpenID/ -> AX.php (source)

   1  <?php
   2  
   3  /**
   4   * Implements the OpenID attribute exchange specification, version 1.0
   5   * as of svn revision 370 from openid.net svn.
   6   *
   7   * @package OpenID
   8   */
   9  
  10  // Do not allow direct access
  11  defined( '_JEXEC' ) or die( 'Restricted access' );
  12  
  13  /**
  14   * Require utility classes and functions for the consumer.
  15   */
  16  require_once "Auth/OpenID/Extension.php";
  17  require_once "Auth/OpenID/Message.php";
  18  require_once "Auth/OpenID/TrustRoot.php";
  19  
  20  define('Auth_OpenID_AX_NS_URI',
  21         'http://openid.net/srv/ax/1.0');
  22  
  23  // Use this as the 'count' value for an attribute in a FetchRequest to
  24  // ask for as many values as the OP can provide.
  25  define('Auth_OpenID_AX_UNLIMITED_VALUES', 'unlimited');
  26  
  27  // Minimum supported alias length in characters.  Here for
  28  // completeness.
  29  define('Auth_OpenID_AX_MINIMUM_SUPPORTED_ALIAS_LENGTH', 32);
  30  
  31  /**
  32   * AX utility class.
  33   *
  34   * @package OpenID
  35   */
  36  class Auth_OpenID_AX {
  37      /**
  38       * @param mixed $thing Any object which may be an
  39       * Auth_OpenID_AX_Error object.
  40       *
  41       * @return bool true if $thing is an Auth_OpenID_AX_Error; false
  42       * if not.
  43       */
  44      function isError($thing)
  45      {
  46          return is_a($thing, 'Auth_OpenID_AX_Error');
  47      }
  48  }
  49  
  50  /**
  51   * Check an alias for invalid characters; raise AXError if any are
  52   * found.  Return None if the alias is valid.
  53   */
  54  function Auth_OpenID_AX_checkAlias($alias)
  55  {
  56    if (strpos($alias, ',') !== false) {
  57        return new Auth_OpenID_AX_Error(sprintf(
  58                     "Alias %s must not contain comma", $alias));
  59    }
  60    if (strpos($alias, '.') !== false) {
  61        return new Auth_OpenID_AX_Error(sprintf(
  62                     "Alias %s must not contain period", $alias));
  63    }
  64  
  65    return true;
  66  }
  67  
  68  /**
  69   * Results from data that does not meet the attribute exchange 1.0
  70   * specification
  71   *
  72   * @package OpenID
  73   */
  74  class Auth_OpenID_AX_Error {
  75      function Auth_OpenID_AX_Error($message=null)
  76      {
  77          $this->message = $message;
  78      }
  79  }
  80  
  81  /**
  82   * Abstract class containing common code for attribute exchange
  83   * messages.
  84   *
  85   * @package OpenID
  86   */
  87  class Auth_OpenID_AX_Message extends Auth_OpenID_Extension {
  88      /**
  89       * ns_alias: The preferred namespace alias for attribute exchange
  90       * messages
  91       */
  92      var $ns_alias = 'ax';
  93  
  94      /**
  95       * mode: The type of this attribute exchange message. This must be
  96       * overridden in subclasses.
  97       */
  98      var $mode = null;
  99  
 100      var $ns_uri = Auth_OpenID_AX_NS_URI;
 101  
 102      /**
 103       * Return Auth_OpenID_AX_Error if the mode in the attribute
 104       * exchange arguments does not match what is expected for this
 105       * class; true otherwise.
 106       *
 107       * @access private
 108       */
 109      function _checkMode($ax_args)
 110      {
 111          $mode = Auth_OpenID::arrayGet($ax_args, 'mode');
 112          if ($mode != $this->mode) {
 113              return new Auth_OpenID_AX_Error(
 114                              sprintf(
 115                                      "Expected mode '%s'; got '%s'",
 116                                      $this->mode, $mode));
 117          }
 118  
 119          return true;
 120      }
 121  
 122      /**
 123       * Return a set of attribute exchange arguments containing the
 124       * basic information that must be in every attribute exchange
 125       * message.
 126       *
 127       * @access private
 128       */
 129      function _newArgs()
 130      {
 131          return array('mode' => $this->mode);
 132      }
 133  }
 134  
 135  /**
 136   * Represents a single attribute in an attribute exchange
 137   * request. This should be added to an AXRequest object in order to
 138   * request the attribute.
 139   *
 140   * @package OpenID
 141   */
 142  class Auth_OpenID_AX_AttrInfo {
 143      /**
 144       * Construct an attribute information object.  Do not call this
 145       * directly; call make(...) instead.
 146       *
 147       * @param string $type_uri The type URI for this attribute.
 148       *
 149       * @param int $count The number of values of this type to request.
 150       *
 151       * @param bool $required Whether the attribute will be marked as
 152       * required in the request.
 153       *
 154       * @param string $alias The name that should be given to this
 155       * attribute in the request.
 156       */
 157      function Auth_OpenID_AX_AttrInfo($type_uri, $count, $required,
 158                                       $alias)
 159      {
 160          /**
 161           * required: Whether the attribute will be marked as required
 162           * when presented to the subject of the attribute exchange
 163           * request.
 164           */
 165          $this->required = $required;
 166  
 167          /**
 168           * count: How many values of this type to request from the
 169           * subject. Defaults to one.
 170           */
 171          $this->count = $count;
 172  
 173          /**
 174           * type_uri: The identifier that determines what the attribute
 175           * represents and how it is serialized. For example, one type
 176           * URI representing dates could represent a Unix timestamp in
 177           * base 10 and another could represent a human-readable
 178           * string.
 179           */
 180          $this->type_uri = $type_uri;
 181  
 182          /**
 183           * alias: The name that should be given to this attribute in
 184           * the request. If it is not supplied, a generic name will be
 185           * assigned. For example, if you want to call a Unix timestamp
 186           * value 'tstamp', set its alias to that value. If two
 187           * attributes in the same message request to use the same
 188           * alias, the request will fail to be generated.
 189           */
 190          $this->alias = $alias;
 191      }
 192  
 193      /**
 194       * Construct an attribute information object.  For parameter
 195       * details, see the constructor.
 196       */
 197      function make($type_uri, $count=1, $required=false,
 198                    $alias=null)
 199      {
 200          if ($alias !== null) {
 201              $result = Auth_OpenID_AX_checkAlias($alias);
 202  
 203              if (Auth_OpenID_AX::isError($result)) {
 204                  return $result;
 205              }
 206          }
 207  
 208          return new Auth_OpenID_AX_AttrInfo($type_uri, $count, $required,
 209                                             $alias);
 210      }
 211  
 212      /**
 213       * When processing a request for this attribute, the OP should
 214       * call this method to determine whether all available attribute
 215       * values were requested.  If self.count == UNLIMITED_VALUES, this
 216       * returns True.  Otherwise this returns False, in which case
 217       * self.count is an integer.
 218      */
 219      function wantsUnlimitedValues()
 220      {
 221          return $this->count === Auth_OpenID_AX_UNLIMITED_VALUES;
 222      }
 223  }
 224  
 225  /**
 226   * Given a namespace mapping and a string containing a comma-separated
 227   * list of namespace aliases, return a list of type URIs that
 228   * correspond to those aliases.
 229   *
 230   * @param $namespace_map The mapping from namespace URI to alias
 231   * @param $alias_list_s The string containing the comma-separated
 232   * list of aliases. May also be None for convenience.
 233   *
 234   * @return $seq The list of namespace URIs that corresponds to the
 235   * supplied list of aliases. If the string was zero-length or None, an
 236   * empty list will be returned.
 237   *
 238   * return null If an alias is present in the list of aliases but
 239   * is not present in the namespace map.
 240   */
 241  function Auth_OpenID_AX_toTypeURIs(&$namespace_map, $alias_list_s)
 242  {
 243      $uris = array();
 244  
 245      if ($alias_list_s) {
 246          foreach (explode(',', $alias_list_s) as $alias) {
 247              $type_uri = $namespace_map->getNamespaceURI($alias);
 248              if ($type_uri === null) {
 249                  // raise KeyError(
 250                  // 'No type is defined for attribute name %r' % (alias,))
 251                  return new Auth_OpenID_AX_Error(
 252                    sprintf('No type is defined for attribute name %s',
 253                            $alias)
 254                    );
 255              } else {
 256                  $uris[] = $type_uri;
 257              }
 258          }
 259      }
 260  
 261      return $uris;
 262  }
 263  
 264  /**
 265   * An attribute exchange 'fetch_request' message. This message is sent
 266   * by a relying party when it wishes to obtain attributes about the
 267   * subject of an OpenID authentication request.
 268   *
 269   * @package OpenID
 270   */
 271  class Auth_OpenID_AX_FetchRequest extends Auth_OpenID_AX_Message {
 272  
 273      var $mode = 'fetch_request';
 274  
 275      function Auth_OpenID_AX_FetchRequest($update_url=null)
 276      {
 277          /**
 278           * requested_attributes: The attributes that have been
 279           * requested thus far, indexed by the type URI.
 280           */
 281          $this->requested_attributes = array();
 282  
 283          /**
 284           * update_url: A URL that will accept responses for this
 285           * attribute exchange request, even in the absence of the user
 286           * who made this request.
 287          */
 288          $this->update_url = $update_url;
 289      }
 290  
 291      /**
 292       * Add an attribute to this attribute exchange request.
 293       *
 294       * @param attribute: The attribute that is being requested
 295       * @return true on success, false when the requested attribute is
 296       * already present in this fetch request.
 297       */
 298      function add($attribute)
 299      {
 300          if ($this->contains($attribute->type_uri)) {
 301              return new Auth_OpenID_AX_Error(
 302                sprintf("The attribute %s has already been requested",
 303                        $attribute->type_uri));
 304          }
 305  
 306          $this->requested_attributes[$attribute->type_uri] = $attribute;
 307  
 308          return true;
 309      }
 310  
 311      /**
 312       * Get the serialized form of this attribute fetch request.
 313       *
 314       * @returns Auth_OpenID_AX_FetchRequest The fetch request message parameters
 315       */
 316      function getExtensionArgs()
 317      {
 318          $aliases = new Auth_OpenID_NamespaceMap();
 319  
 320          $required = array();
 321          $if_available = array();
 322  
 323          $ax_args = $this->_newArgs();
 324  
 325          foreach ($this->requested_attributes as $type_uri => $attribute) {
 326              if ($attribute->alias === null) {
 327                  $alias = $aliases->add($type_uri);
 328              } else {
 329                  $alias = $aliases->addAlias($type_uri, $attribute->alias);
 330  
 331                  if ($alias === null) {
 332                      return new Auth_OpenID_AX_Error(
 333                        sprintf("Could not add alias %s for URI %s",
 334                                $attribute->alias, $type_uri
 335                        ));
 336                  }
 337              }
 338  
 339              if ($attribute->required) {
 340                  $required[] = $alias;
 341              } else {
 342                  $if_available[] = $alias;
 343              }
 344  
 345              if ($attribute->count != 1) {
 346                  $ax_args['count.' . $alias] = strval($attribute->count);
 347              }
 348  
 349              $ax_args['type.' . $alias] = $type_uri;
 350          }
 351  
 352          if ($required) {
 353              $ax_args['required'] = implode(',', $required);
 354          }
 355  
 356          if ($if_available) {
 357              $ax_args['if_available'] = implode(',', $if_available);
 358          }
 359  
 360          return $ax_args;
 361      }
 362  
 363      /**
 364       * Get the type URIs for all attributes that have been marked as
 365       * required.
 366       *
 367       * @return A list of the type URIs for attributes that have been
 368       * marked as required.
 369       */
 370      function getRequiredAttrs()
 371      {
 372          $required = array();
 373          foreach ($this->requested_attributes as $type_uri => $attribute) {
 374              if ($attribute->required) {
 375                  $required[] = $type_uri;
 376              }
 377          }
 378  
 379          return $required;
 380      }
 381  
 382      /**
 383       * Extract a FetchRequest from an OpenID message
 384       *
 385       * @param request: The OpenID request containing the attribute
 386       * fetch request
 387       *
 388       * @returns mixed An Auth_OpenID_AX_Error or the
 389       * Auth_OpenID_AX_FetchRequest extracted from the request message if
 390       * successful
 391       */
 392      function &fromOpenIDRequest($request)
 393      {
 394          $m = $request->message;
 395          $obj = new Auth_OpenID_AX_FetchRequest();
 396          $ax_args = $m->getArgs($obj->ns_uri);
 397  
 398          $result = $obj->parseExtensionArgs($ax_args);
 399  
 400          if (Auth_OpenID_AX::isError($result)) {
 401              return $result;
 402          }
 403  
 404          if ($obj->update_url) {
 405              // Update URL must match the openid.realm of the
 406              // underlying OpenID 2 message.
 407              $realm = $m->getArg(Auth_OpenID_OPENID_NS, 'realm',
 408                          $m->getArg(
 409                                    Auth_OpenID_OPENID_NS,
 410                                    'return_to'));
 411  
 412              if (!$realm) {
 413                  $obj = new Auth_OpenID_AX_Error(
 414                    sprintf("Cannot validate update_url %s " .
 415                            "against absent realm", $obj->update_url));
 416              } else if (!Auth_OpenID_TrustRoot::match($realm,
 417                                                       $obj->update_url)) {
 418                  $obj = new Auth_OpenID_AX_Error(
 419                    sprintf("Update URL %s failed validation against realm %s",
 420                            $obj->update_url, $realm));
 421              }
 422          }
 423  
 424          return $obj;
 425      }
 426  
 427      /**
 428       * Given attribute exchange arguments, populate this FetchRequest.
 429       *
 430       * @return $result Auth_OpenID_AX_Error if the data to be parsed
 431       * does not follow the attribute exchange specification. At least
 432       * when 'if_available' or 'required' is not specified for a
 433       * particular attribute type.  Returns true otherwise.
 434      */
 435      function parseExtensionArgs($ax_args)
 436      {
 437          $result = $this->_checkMode($ax_args);
 438          if (Auth_OpenID_AX::isError($result)) {
 439              return $result;
 440          }
 441  
 442          $aliases = new Auth_OpenID_NamespaceMap();
 443  
 444          foreach ($ax_args as $key => $value) {
 445              if (strpos($key, 'type.') === 0) {
 446                  $alias = substr($key, 5);
 447                  $type_uri = $value;
 448  
 449                  $alias = $aliases->addAlias($type_uri, $alias);
 450  
 451                  if ($alias === null) {
 452                      return new Auth_OpenID_AX_Error(
 453                        sprintf("Could not add alias %s for URI %s",
 454                                $alias, $type_uri)
 455                        );
 456                  }
 457  
 458                  $count_s = Auth_OpenID::arrayGet($ax_args, 'count.' . $alias);
 459                  if ($count_s) {
 460                      $count = Auth_OpenID::intval($count_s);
 461                      if (($count === false) &&
 462                          ($count_s === Auth_OpenID_AX_UNLIMITED_VALUES)) {
 463                          $count = $count_s;
 464                      }
 465                  } else {
 466                      $count = 1;
 467                  }
 468  
 469                  if ($count === false) {
 470                      return new Auth_OpenID_AX_Error(
 471                        sprintf("Integer value expected for %s, got %s",
 472                                'count.' . $alias, $count_s));
 473                  }
 474  
 475                  $attrinfo = Auth_OpenID_AX_AttrInfo::make($type_uri, $count,
 476                                                            false, $alias);
 477  
 478                  if (Auth_OpenID_AX::isError($attrinfo)) {
 479                      return $attrinfo;
 480                  }
 481  
 482                  $this->add($attrinfo);
 483              }
 484          }
 485  
 486          $required = Auth_OpenID_AX_toTypeURIs($aliases,
 487                           Auth_OpenID::arrayGet($ax_args, 'required'));
 488  
 489          foreach ($required as $type_uri) {
 490              $attrib =& $this->requested_attributes[$type_uri];
 491              $attrib->required = true;
 492          }
 493  
 494          $if_available = Auth_OpenID_AX_toTypeURIs($aliases,
 495                               Auth_OpenID::arrayGet($ax_args, 'if_available'));
 496  
 497          $all_type_uris = array_merge($required, $if_available);
 498  
 499          foreach ($aliases->iterNamespaceURIs() as $type_uri) {
 500              if (!in_array($type_uri, $all_type_uris)) {
 501                  return new Auth_OpenID_AX_Error(
 502                    sprintf('Type URI %s was in the request but not ' .
 503                            'present in "required" or "if_available"',
 504                            $type_uri));
 505  
 506              }
 507          }
 508  
 509          $this->update_url = Auth_OpenID::arrayGet($ax_args, 'update_url');
 510  
 511          return true;
 512      }
 513  
 514      /**
 515       * Iterate over the AttrInfo objects that are contained in this
 516       * fetch_request.
 517       */
 518      function iterAttrs()
 519      {
 520          return array_values($this->requested_attributes);
 521      }
 522  
 523      function iterTypes()
 524      {
 525          return array_keys($this->requested_attributes);
 526      }
 527  
 528      /**
 529       * Is the given type URI present in this fetch_request?
 530       */
 531      function contains($type_uri)
 532      {
 533          return in_array($type_uri, $this->iterTypes());
 534      }
 535  }
 536  
 537  /**
 538   * An abstract class that implements a message that has attribute keys
 539   * and values. It contains the common code between fetch_response and
 540   * store_request.
 541   *
 542   * @package OpenID
 543   */
 544  class Auth_OpenID_AX_KeyValueMessage extends Auth_OpenID_AX_Message {
 545  
 546      function Auth_OpenID_AX_KeyValueMessage()
 547      {
 548          $this->data = array();
 549      }
 550  
 551      /**
 552       * Add a single value for the given attribute type to the
 553       * message. If there are already values specified for this type,
 554       * this value will be sent in addition to the values already
 555       * specified.
 556       *
 557       * @param type_uri: The URI for the attribute
 558       * @param value: The value to add to the response to the relying
 559       * party for this attribute
 560       * @return null
 561       */
 562      function addValue($type_uri, $value)
 563      {
 564          if (!array_key_exists($type_uri, $this->data)) {
 565              $this->data[$type_uri] = array();
 566          }
 567  
 568          $values =& $this->data[$type_uri];
 569          $values[] = $value;
 570      }
 571  
 572      /**
 573       * Set the values for the given attribute type. This replaces any
 574       * values that have already been set for this attribute.
 575       *
 576       * @param type_uri: The URI for the attribute
 577       * @param values: A list of values to send for this attribute.
 578       */
 579      function setValues($type_uri, &$values)
 580      {
 581          $this->data[$type_uri] =& $values;
 582      }
 583  
 584      /**
 585       * Get the extension arguments for the key/value pairs contained
 586       * in this message.
 587       *
 588       * @param aliases: An alias mapping. Set to None if you don't care
 589       * about the aliases for this request.
 590       *
 591       * @access private
 592       */
 593      function _getExtensionKVArgs(&$aliases)
 594      {
 595          if ($aliases === null) {
 596              $aliases = new Auth_OpenID_NamespaceMap();
 597          }
 598  
 599          $ax_args = array();
 600  
 601          foreach ($this->data as $type_uri => $values) {
 602              $alias = $aliases->add($type_uri);
 603  
 604              $ax_args['type.' . $alias] = $type_uri;
 605              $ax_args['count.' . $alias] = strval(count($values));
 606  
 607              foreach ($values as $i => $value) {
 608                $key = sprintf('value.%s.%d', $alias, $i + 1);
 609                $ax_args[$key] = $value;
 610              }
 611          }
 612  
 613          return $ax_args;
 614      }
 615  
 616      /**
 617       * Parse attribute exchange key/value arguments into this object.
 618       *
 619       * @param ax_args: The attribute exchange fetch_response
 620       * arguments, with namespacing removed.
 621       *
 622       * @return Auth_OpenID_AX_Error or true
 623       */
 624      function parseExtensionArgs($ax_args)
 625      {
 626          $result = $this->_checkMode($ax_args);
 627          if (Auth_OpenID_AX::isError($result)) {
 628              return $result;
 629          }
 630  
 631          $aliases = new Auth_OpenID_NamespaceMap();
 632  
 633          foreach ($ax_args as $key => $value) {
 634              if (strpos($key, 'type.') === 0) {
 635                  $type_uri = $value;
 636                  $alias = substr($key, 5);
 637  
 638                  $result = Auth_OpenID_AX_checkAlias($alias);
 639  
 640                  if (Auth_OpenID_AX::isError($result)) {
 641                      return $result;
 642                  }
 643  
 644                  $alias = $aliases->addAlias($type_uri, $alias);
 645  
 646                  if ($alias === null) {
 647                      return new Auth_OpenID_AX_Error(
 648                        sprintf("Could not add alias %s for URI %s",
 649                                $alias, $type_uri)
 650                        );
 651                  }
 652              }
 653          }
 654  
 655          foreach ($aliases->iteritems() as $pair) {
 656              list($type_uri, $alias) = $pair;
 657  
 658              if (array_key_exists('count.' . $alias, $ax_args)) {
 659  
 660                  $count_key = 'count.' . $alias;
 661                  $count_s = $ax_args[$count_key];
 662  
 663                  $count = Auth_OpenID::intval($count_s);
 664  
 665                  if ($count === false) {
 666                      return new Auth_OpenID_AX_Error(
 667                        sprintf("Integer value expected for %s, got %s",
 668                                'count. %s' . $alias, $count_s,
 669                                Auth_OpenID_AX_UNLIMITED_VALUES)
 670                                                      );
 671                  }
 672  
 673                  $values = array();
 674                  for ($i = 1; $i < $count + 1; $i++) {
 675                      $value_key = sprintf('value.%s.%d', $alias, $i);
 676  
 677                      if (!array_key_exists($value_key, $ax_args)) {
 678                        return new Auth_OpenID_AX_Error(
 679                          sprintf(
 680                                  "No value found for key %s",
 681                                  $value_key));
 682                      }
 683  
 684                      $value = $ax_args[$value_key];
 685                      $values[] = $value;
 686                  }
 687              } else {
 688                  $key = 'value.' . $alias;
 689  
 690                  if (!array_key_exists($key, $ax_args)) {
 691                    return new Auth_OpenID_AX_Error(
 692                      sprintf(
 693                              "No value found for key %s",
 694                              $key));
 695                  }
 696  
 697                  $value = $ax_args['value.' . $alias];
 698  
 699                  if ($value == '') {
 700                      $values = array();
 701                  } else {
 702                      $values = array($value);
 703                  }
 704              }
 705  
 706              $this->data[$type_uri] = $values;
 707          }
 708  
 709          return true;
 710      }
 711  
 712      /**
 713       * Get a single value for an attribute. If no value was sent for
 714       * this attribute, use the supplied default. If there is more than
 715       * one value for this attribute, this method will fail.
 716       *
 717       * @param type_uri: The URI for the attribute
 718       * @param default: The value to return if the attribute was not
 719       * sent in the fetch_response.
 720       *
 721       * @return $value Auth_OpenID_AX_Error on failure or the value of
 722       * the attribute in the fetch_response message, or the default
 723       * supplied
 724       */
 725      function getSingle($type_uri, $default=null)
 726      {
 727          $values = Auth_OpenID::arrayGet($this->data, $type_uri);
 728          if (!$values) {
 729              return $default;
 730          } else if (count($values) == 1) {
 731              return $values[0];
 732          } else {
 733              return new Auth_OpenID_AX_Error(
 734                sprintf('More than one value present for %s',
 735                        $type_uri)
 736                );
 737          }
 738      }
 739  
 740      /**
 741       * Get the list of values for this attribute in the
 742       * fetch_response.
 743       *
 744       * XXX: what to do if the values are not present? default
 745       * parameter? this is funny because it's always supposed to return
 746       * a list, so the default may break that, though it's provided by
 747       * the user's code, so it might be okay. If no default is
 748       * supplied, should the return be None or []?
 749       *
 750       * @param type_uri: The URI of the attribute
 751       *
 752       * @return $values The list of values for this attribute in the
 753       * response. May be an empty list.  If the attribute was not sent
 754       * in the response, returns Auth_OpenID_AX_Error.
 755       */
 756      function get($type_uri)
 757      {
 758          if (array_key_exists($type_uri, $this->data)) {
 759              return $this->data[$type_uri];
 760          } else {
 761              return new Auth_OpenID_AX_Error(
 762                sprintf("Type URI %s not found in response",
 763                        $type_uri)
 764                );
 765          }
 766      }
 767  
 768      /**
 769       * Get the number of responses for a particular attribute in this
 770       * fetch_response message.
 771       *
 772       * @param type_uri: The URI of the attribute
 773       *
 774       * @returns int The number of values sent for this attribute.  If
 775       * the attribute was not sent in the response, returns
 776       * Auth_OpenID_AX_Error.
 777       */
 778      function count($type_uri)
 779      {
 780          if (array_key_exists($type_uri, $this->data)) {
 781              return count($this->get($type_uri));
 782          } else {
 783              return new Auth_OpenID_AX_Error(
 784                sprintf("Type URI %s not found in response",
 785                        $type_uri)
 786                );
 787          }
 788      }
 789  }
 790  
 791  /**
 792   * A fetch_response attribute exchange message.
 793   *
 794   * @package OpenID
 795   */
 796  class Auth_OpenID_AX_FetchResponse extends Auth_OpenID_AX_KeyValueMessage {
 797      var $mode = 'fetch_response';
 798  
 799      function Auth_OpenID_AX_FetchResponse($update_url=null)
 800      {
 801          $this->Auth_OpenID_AX_KeyValueMessage();
 802          $this->update_url = $update_url;
 803      }
 804  
 805      /**
 806       * Serialize this object into arguments in the attribute exchange
 807       * namespace
 808       *
 809       * @return $args The dictionary of unqualified attribute exchange
 810       * arguments that represent this fetch_response, or
 811       * Auth_OpenID_AX_Error on error.
 812       */
 813      function getExtensionArgs($request=null)
 814      {
 815          $aliases = new Auth_OpenID_NamespaceMap();
 816  
 817          $zero_value_types = array();
 818  
 819          if ($request !== null) {
 820              // Validate the data in the context of the request (the
 821              // same attributes should be present in each, and the
 822              // counts in the response must be no more than the counts
 823              // in the request)
 824  
 825              foreach ($this->data as $type_uri => $unused) {
 826                  if (!$request->contains($type_uri)) {
 827                      return new Auth_OpenID_AX_Error(
 828                        sprintf("Response attribute not present in request: %s",
 829                                $type_uri)
 830                        );
 831                  }
 832              }
 833  
 834              foreach ($request->iterAttrs() as $attr_info) {
 835                  // Copy the aliases from the request so that reading
 836                  // the response in light of the request is easier
 837                  if ($attr_info->alias === null) {
 838                      $aliases->add($attr_info->type_uri);
 839                  } else {
 840                      $alias = $aliases->addAlias($attr_info->type_uri,
 841                                                  $attr_info->alias);
 842  
 843                      if ($alias === null) {
 844                          return new Auth_OpenID_AX_Error(
 845                            sprintf("Could not add alias %s for URI %s",
 846                                    $attr_info->alias, $attr_info->type_uri)
 847                            );
 848                      }
 849                  }
 850  
 851                  if (array_key_exists($attr_info->type_uri, $this->data)) {
 852                      $values = $this->data[$attr_info->type_uri];
 853                  } else {
 854                      $values = array();
 855                      $zero_value_types[] = $attr_info;
 856                  }
 857  
 858                  if (($attr_info->count != Auth_OpenID_AX_UNLIMITED_VALUES) &&
 859                      ($attr_info->count < count($values))) {
 860                      return new Auth_OpenID_AX_Error(
 861                        sprintf("More than the number of requested values " .
 862                                "were specified for %s",
 863                                $attr_info->type_uri)
 864                        );
 865                  }
 866              }
 867          }
 868  
 869          $kv_args = $this->_getExtensionKVArgs($aliases);
 870  
 871          // Add the KV args into the response with the args that are
 872          // unique to the fetch_response
 873          $ax_args = $this->_newArgs();
 874  
 875          // For each requested attribute, put its type/alias and count
 876          // into the response even if no data were returned.
 877          foreach ($zero_value_types as $attr_info) {
 878              $alias = $aliases->getAlias($attr_info->type_uri);
 879              $kv_args['type.' . $alias] = $attr_info->type_uri;
 880              $kv_args['count.' . $alias] = '0';
 881          }
 882  
 883          $update_url = null;
 884          if ($request) {
 885              $update_url = $request->update_url;
 886          } else {
 887              $update_url = $this->update_url;
 888          }
 889  
 890          if ($update_url) {
 891              $ax_args['update_url'] = $update_url;
 892          }
 893  
 894          Auth_OpenID::update(&$ax_args, $kv_args);
 895  
 896          return $ax_args;
 897      }
 898  
 899      /**
 900       * @return $result Auth_OpenID_AX_Error on failure or true on
 901       * success.
 902       */
 903      function parseExtensionArgs($ax_args)
 904      {
 905          $result = parent::parseExtensionArgs($ax_args);
 906  
 907          if (Auth_OpenID_AX::isError($result)) {
 908              return $result;
 909          }
 910  
 911          $this->update_url = Auth_OpenID::arrayGet($ax_args, 'update_url');
 912  
 913          return true;
 914      }
 915  
 916      /**
 917       * Construct a FetchResponse object from an OpenID library
 918       * SuccessResponse object.
 919       *
 920       * @param success_response: A successful id_res response object
 921       *
 922       * @param signed: Whether non-signed args should be processsed. If
 923       * True (the default), only signed arguments will be processsed.
 924       *
 925       * @return $response A FetchResponse containing the data from the
 926       * OpenID message
 927       */
 928      function fromSuccessResponse($success_response, $signed=true)
 929      {
 930          $obj = new Auth_OpenID_AX_FetchResponse();
 931          if ($signed) {
 932              $ax_args = $success_response->getSignedNS($obj->ns_uri);
 933          } else {
 934              $ax_args = $success_response->message->getArgs($obj->ns_uri);
 935          }
 936          if ($ax_args === null || Auth_OpenID::isFailure($ax_args) ||
 937                sizeof($ax_args) == 0) {
 938              return null;
 939          }
 940  
 941          $result = $obj->parseExtensionArgs($ax_args);
 942          if (Auth_OpenID_AX::isError($result)) {
 943              #XXX log me
 944              return null;
 945          }
 946          return $obj;
 947      }
 948  }
 949  
 950  /**
 951   * A store request attribute exchange message representation.
 952   *
 953   * @package OpenID
 954   */
 955  class Auth_OpenID_AX_StoreRequest extends Auth_OpenID_AX_KeyValueMessage {
 956      var $mode = 'store_request';
 957  
 958      /**
 959       * @param array $aliases The namespace aliases to use when making
 960       * this store response. Leave as None to use defaults.
 961       */
 962      function getExtensionArgs($aliases=null)
 963      {
 964          $ax_args = $this->_newArgs();
 965          $kv_args = $this->_getExtensionKVArgs($aliases);
 966          Auth_OpenID::update(&$ax_args, $kv_args);
 967          return $ax_args;
 968      }
 969  }
 970  
 971  /**
 972   * An indication that the store request was processed along with this
 973   * OpenID transaction.  Use make(), NOT the constructor, to create
 974   * response objects.
 975   *
 976   * @package OpenID
 977   */
 978  class Auth_OpenID_AX_StoreResponse extends Auth_OpenID_AX_Message {
 979      var $SUCCESS_MODE = 'store_response_success';
 980      var $FAILURE_MODE = 'store_response_failure';
 981  
 982      /**
 983       * Returns Auth_OpenID_AX_Error on error or an
 984       * Auth_OpenID_AX_StoreResponse object on success.
 985       */
 986      function &make($succeeded=true, $error_message=null)
 987      {
 988          if (($succeeded) && ($error_message !== null)) {
 989              return new Auth_OpenID_AX_Error('An error message may only be '.
 990                                      'included in a failing fetch response');
 991          }
 992  
 993          return new Auth_OpenID_AX_StoreResponse($succeeded, $error_message);
 994      }
 995  
 996      function Auth_OpenID_AX_StoreResponse($succeeded=true, $error_message=null)
 997      {
 998          if ($succeeded) {
 999              $this->mode = $this->SUCCESS_MODE;
1000          } else {
1001              $this->mode = $this->FAILURE_MODE;
1002          }
1003  
1004          $this->error_message = $error_message;
1005      }
1006  
1007      /**
1008       * Was this response a success response?
1009       */
1010      function succeeded()
1011      {
1012          return $this->mode == $this->SUCCESS_MODE;
1013      }
1014  
1015      function getExtensionArgs()
1016      {
1017          $ax_args = $this->_newArgs();
1018          if ((!$this->succeeded()) && $this->error_message) {
1019              $ax_args['error'] = $this->error_message;
1020          }
1021  
1022          return $ax_args;
1023      }
1024  }
1025  
1026  ?>


Generated: Wed Mar 28 15:54:07 2012 Cross-referenced by PHPXref 0.7.1