Support Joomla!

Packages

Package: OpenID

License

Content on this site is copyright © 2005 - 2008 Open Source Matters Inc and can be used in accordance with the Joomla! Electronic Documentation License. Some parts of this website may be subject to other licenses.
Source code for file /openid/Auth/OpenID/AX.php

Documentation is available at AX.php

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

Documentation generated on Sat, 14 Nov 2009 11:10:55 +0000 by phpDocumentor 1.3.1