Author: as
Date: Wed Aug  8 16:41:23 2007
New Revision: 5849

Log:
- Implemented feature request #10971: Added the possibility to fetch extra
  data during authentication for Database, LDAP, OpenID and TypeKey filters.

Added:
    trunk/Authentication/src/interfaces/
    trunk/Authentication/src/interfaces/data_fetch.php   (with props)
Modified:
    trunk/Authentication/ChangeLog
    trunk/Authentication/design/class_diagram.png
    trunk/Authentication/docs/tutorial.txt
    trunk/Authentication/src/authentication_autoload.php
    trunk/Authentication/src/filters/ldap/ldap_filter.php
    trunk/Authentication/src/filters/openid/openid_filter.php
    trunk/Authentication/src/filters/typekey/typekey_filter.php
    trunk/Authentication/tests/filters/ldap/ldap_test.php
    trunk/Authentication/tests/filters/openid/openid_test.php
    trunk/Authentication/tests/filters/typekey/typekey_test.php

Modified: trunk/Authentication/ChangeLog
==============================================================================
--- trunk/Authentication/ChangeLog [iso-8859-1] (original)
+++ trunk/Authentication/ChangeLog [iso-8859-1] Wed Aug  8 16:41:23 2007
@@ -3,6 +3,8 @@
 
 - Implemented feature request #10998: Added a Database backend for OpenID
   authentication.
+- Implemented feature request #10971: Added the possibility to fetch extra
+  data during authentication for Database, LDAP, OpenID and TypeKey filters.
 
 
 1.0 - Monday 02 July 2007

Modified: trunk/Authentication/design/class_diagram.png
==============================================================================
Binary files - no diff available.

Modified: trunk/Authentication/docs/tutorial.txt
==============================================================================
--- trunk/Authentication/docs/tutorial.txt [iso-8859-1] (original)
+++ trunk/Authentication/docs/tutorial.txt [iso-8859-1] Wed Aug  8 16:41:23 2007
@@ -241,6 +241,30 @@
 content.
 
 
+Fetch extra data during LDAP authentication
+```````````````````````````````````````````
+
+Any data that is defined for an acount can be fetched. Before running the
+authentication process (before calling run(), register which data needs to be
+fetched. Example: ::
+
+    // $filter is an ezcAuthenticationLdapFilter object
+    $filter->registerFetchData( array( 'name', 'company', 'mobile' ) );
+
+After the authentication process is finished (after run()), retrieve the data
+that was registered: ::
+
+    // $filter is an ezcAuthenticationLdapFilter object
+    $data = $filter->fetchData();
+
+For the previous example, the $data array will be something like this: ::
+
+    array( 'name' => array( 'Dr. No' ),
+           'company' => array( 'SPECTRE' ),
+           'mobile' => array( '555-7732873' )
+         );
+
+
 OpenID
 ------
 
@@ -344,6 +368,36 @@
 the store will also hold the nonces which are used to prevent replay attacks.
 
 
+    // $filter is an ezcAuthenticationLdapFilter object
+    $filter->registerFetchData( array( 'name', 'company', 'mobile' ) );
+
+
+Fetch extra data during OpenID authentication
+`````````````````````````````````````````````
+
+Any data that is defined for an acount can be fetched. Before running the
+authentication process (before calling run(), register which data needs to be
+fetched. Example: ::
+
+    // $filter is an ezcAuthenticationOpenidFilter object
+    $filter->registerFetchData( array( 'fullname', 'gender', 'country',
+    'language' ) );
+
+After the authentication process is finished (after run()), retrieve the data
+that was registered: ::
+
+    // $filter is an ezcAuthenticationOpenidFilter object
+    $data = $filter->fetchData();
+
+For the previous example, the $data array will be something like this: ::
+
+    array( 'fullname' => array( 'John Doe' ),
+           'gender' => array( 'M' ),
+           'country' => array( 'US' ),
+           'language' => array( 'FR' )
+         );
+
+
 Token
 -----
 
@@ -414,6 +468,31 @@
 content.
 
 
+Fetch extra data during TypeKey authentication
+``````````````````````````````````````````````
+
+The extra data that can be fetched is name (the TypeKey username), nick (the
+TypeKey display name) and email (the user email address). The email address can
+only be fetched if need_email was included in the initial request to the
+TypeKey server with a value other than 0, and if the user allowed the sharing
+of his email address. Example: ::
+
+    
https://www.typekey.com/t/typekey/login?t=<token>&_return=<url>&need_email=1
+
+After the authentication process is finished (after run()), retrieve the extra
+data: ::
+
+    // $filter is an ezcAuthenticationTypekeyFilter object
+    $data = $filter->fetchData();
+
+The $data array will be something like this: ::
+
+    array( 'name' => array( 'john' ),
+           'nick' => array( 'John Doe' ),
+           'email' => array( '[EMAIL PROTECTED]' ) // or not set
+         );
+
+
 Securing applications
 =====================
 

Modified: trunk/Authentication/src/authentication_autoload.php
==============================================================================
--- trunk/Authentication/src/authentication_autoload.php [iso-8859-1] (original)
+++ trunk/Authentication/src/authentication_autoload.php [iso-8859-1] Wed Aug  
8 16:41:23 2007
@@ -16,6 +16,7 @@
     'ezcAuthenticationTypekeyException'       => 
'Authentication/exceptions/typekey_exception.php',
     'ezcAuthenticationBignumLibrary'          => 
'Authentication/math/bignum_library.php',
     'ezcAuthenticationCredentials'            => 
'Authentication/credentials/credentials.php',
+    'ezcAuthenticationDataFetch'              => 
'Authentication/interfaces/data_fetch.php',
     'ezcAuthenticationFilter'                 => 
'Authentication/filters/authentication_filter.php',
     'ezcAuthenticationFilterOptions'          => 
'Authentication/options/filter_options.php',
     'ezcAuthenticationOpenidStore'            => 
'Authentication/filters/openid/openid_store.php',

Modified: trunk/Authentication/src/filters/ldap/ldap_filter.php
==============================================================================
--- trunk/Authentication/src/filters/ldap/ldap_filter.php [iso-8859-1] 
(original)
+++ trunk/Authentication/src/filters/ldap/ldap_filter.php [iso-8859-1] Wed Aug  
8 16:41:23 2007
@@ -46,6 +46,24 @@
  * }
  * </code>
  *
+ * Extra data can be fetched from the LDAP server during the authentication
+ * process, by registering the data to be fetched before calling run(). 
Example:
+ * <code>
+ * // $filter is an ezcAuthenticationLdapFilter object
+ * $filter->registerFetchData( array( 'name', 'company', 'mobile' ) );
+ *
+ * // after run()
+ * $data = $filter->fetchData();
+ * </code>
+ *
+ * The $data array will be something like:
+ * <code>
+ * array( 'name' = > array( 'Dr. No' ),
+ *        'company' => array( 'SPECTRE' ),
+ *        'mobile' => array( '555-7732873' )
+ *      );
+ * </code>
+ *
  * @property ezcAuthenticationLdapInfo $ldap
  *           Structure which holds the LDAP server hostname, entry format and 
base,
  *           and port.
@@ -54,7 +72,7 @@
  * @version //autogen//
  * @mainclass
  */
-class ezcAuthenticationLdapFilter extends ezcAuthenticationFilter
+class ezcAuthenticationLdapFilter extends ezcAuthenticationFilter implements 
ezcAuthenticationDataFetch
 {
     /**
      * Username is not found in the database.
@@ -75,6 +93,34 @@
      * Use plain-text password and TLS connection.
      */
     const PROTOCOL_TLS = 2;
+
+    /**
+     * Holds the attributes which will be requested during the authentication
+     * process.
+     *
+     * Usually it has this structure:
+     * <code>
+     * array( 'name', 'company', 'mobile' );
+     * </code>
+     *
+     * @var array(string)
+     */
+    protected $requestedData = array();
+
+    /**
+     * Holds the extra data fetched during the authentication process.
+     *
+     * Usually it has this structure:
+     * <code>
+     * array( 'name' = > array( 'Dr. No' ),
+     *        'company' => array( 'SPECTRE' ),
+     *        'mobile' => array( '555-7732873' )
+     *      );
+     * </code>
+     *
+     * @var array(string=>mixed)
+     */
+    protected $data = array();
 
     /**
      * Holds the properties of this class.
@@ -219,7 +265,7 @@
         // bind anonymously to see if username exists in the directory
         if ( @ldap_bind( $connection ) )
         {
-            $search = ldap_list( $connection, $this->ldap->base, str_replace( 
'%id%', $credentials->id, $this->ldap->format ) );
+            $search = ldap_list( $connection, $this->ldap->base, str_replace( 
'%id%', $credentials->id, $this->ldap->format ), $this->requestedData );
             if ( ldap_count_entries( $connection, $search ) === 0 )
             {
                 ldap_close( $connection );
@@ -229,6 +275,21 @@
             // username exists, so check if we can bind with the provided 
password
             if ( @ldap_bind( $connection, str_replace( '%id%', 
$credentials->id, $this->ldap->format ) . ',' . $this->ldap->base, 
$credentials->password ) )
             {
+                if ( count( $this->requestedData ) > 0 )
+                {
+                    $entries = ldap_get_entries( $connection, $search );
+                    $entry = $entries[0];
+
+
+                    foreach ( $this->requestedData as $attribute )
+                    {
+                        for ( $i = 0; $i < $entry[$attribute]['count']; $i++ )
+                        {
+                            $this->data[$attribute][] = $entry[$attribute][$i];
+                        }
+                    }
+                }
+
                 ldap_close( $connection );
                 return self::STATUS_OK;
             }
@@ -282,5 +343,38 @@
     {
         return @ldap_start_tls( $connection );
     }
+
+    /**
+     * Registers which extra data to fetch during the authentication process.
+     *
+     * The input $data is an array of attributes to request, for example:
+     * <code>
+     * array( 'name', 'company', 'mobile' );
+     * </code>
+     *
+     * @param array(string) A list of attributes to fetch during authentication
+     */
+    public function registerFetchData( array $data = array() )
+    {
+        $this->requestedData = $data;
+    }
+
+    /**
+     * Returns the extra data fetched during the authentication process.
+     *
+     * The return is something like:
+     * <code>
+     * array( 'name' = > array( 'Dr. No' ),
+     *        'company' => array( 'SPECTRE' ),
+     *        'mobile' => array( '555-7732873' )
+     *      );
+     * </code>
+     *
+     * @param array(string=>mixed)
+     */
+    public function fetchData()
+    {
+        return $this->data;
+    }
 }
 ?>

Modified: trunk/Authentication/src/filters/openid/openid_filter.php
==============================================================================
--- trunk/Authentication/src/filters/openid/openid_filter.php [iso-8859-1] 
(original)
+++ trunk/Authentication/src/filters/openid/openid_filter.php [iso-8859-1] Wed 
Aug  8 16:41:23 2007
@@ -10,7 +10,7 @@
  */
 
 /**
- * Filter to authenticate against OpenID. Currently supporting OpenID 1.1.
+ * Filter to authenticate against OpenID. Currently supporting OpenID 1.0 and 
1.1.
  *
  * The filter takes an identifier (URL) as credentials, and performs these 
steps:
  *  1. Normalize the identifier
@@ -116,12 +116,48 @@
  * // ...
  * </code>
  *
+ * Extra data can be fetched from the OpenID provider during the authentication
+ * process, by registering the data to be fetched before calling run(). 
Example:
+ * <code>
+ * // $filter is an ezcAuthenticationOpenidFilter object
+ * $filter->registerFetchData( array( 'fullname', 'gender', 'country', 
'language' ) );
+ *
+ * // after run()
+ * $data = $filter->fetchData();
+ * </code>
+ *
+ * The $data array will be something like:
+ * <code>
+ * array( 'fullname' => array( 'John Doe' ),
+ *        'gender' => array( 'M' ),
+ *        'country' => array( 'US' ),
+ *        'language' => array( 'FR' )
+ *      );
+ * </code>
+ *
+ * The extra data which is possible to be fetched during the authentication
+ * process is:
+ *  - nickname - the user's nickname (short name, alias)
+ *  - email - the user's email address
+ *  - fullname - the user's full name
+ *  - dob - the user's date of birth as YYYY-MM-DD. Any component value whose
+ *    representation uses fewer than the specified number of digits should
+ *    be zero-padded (eg. 02 for February). If the user does not want to
+ *    reveal any particular component of this value, it should be zero
+ *    (eg. "1980-00-00" if the user is born in 1980 but does not want to
+ *    specify his month and day of birth)
+ *  - gender - the user's gender, "M" for male, "F" for female
+ *  - postcode - the user's postal code
+ *  - country - the user's country as an ISO3166 string, (eg. "US")
+ *  - language - the user's preferred language as an ISO639 string (eg. "FR")
+ *  - timezone - the user's timezone, for example "Europe/Paris"
+ *
+ * @todo add support for fetching extra data as in OpenID attribute exchange?
+ *       (if needed) - [EMAIL PROTECTED] http://openid.net/specs.bml}
  * @todo add support for multiple URLs in each category at discovery
  * @todo add support for OpenID 2.0 
(openid.ns=http://specs.openid.net/auth/2.0),
  *       and add support for XRI identifiers and discovery
  *       Question: is 2.0 already out or is it still a draft?
- * @todo make OpenID 1.0 support better.
- *       Question: is 1.0 still used?
  * @todo add support for checkid_immediate
  * @todo check if the nonce handling is correct (openid.response_nonce?)
  *
@@ -129,7 +165,7 @@
  * @version //autogen//
  * @mainclass
  */
-class ezcAuthenticationOpenidFilter extends ezcAuthenticationFilter
+class ezcAuthenticationOpenidFilter extends ezcAuthenticationFilter implements 
ezcAuthenticationDataFetch
 {
     /**
      * The OpenID provider did not authorize the provided URL.
@@ -190,6 +226,35 @@
      * @ignore
      */
     const DEFAULT_Q = '2';
+
+    /**
+     * Holds the attributes which will be requested during the authentication
+     * process.
+     *
+     * Usually it has this structure:
+     * <code>
+     * array( 'fullname', 'gender', 'country', 'language' );
+     * </code>
+     *
+     * @var array(string)
+     */
+    protected $requestedData = array();
+
+    /**
+     * Holds the extra data fetched during the authentication process.
+     *
+     * Usually it has this structure:
+     * <code>
+     * array( 'fullname' => array( 'John Doe' ),
+     *        'gender' => array( 'M' ),
+     *        'country' => array( 'NO' ),
+     *        'language' => array( 'FR' )
+     *      );
+     * </code>
+     *
+     * @var array(string=>mixed)
+     */
+    protected $data = array();
 
     /**
      * Creates a new object of this class.
@@ -287,8 +352,13 @@
                     'openid.return_to' => urlencode( $returnTo ),
                     'openid.trust_root' => urlencode( $trustRoot ),
                     'openid.identity' => urlencode( $identity ),
-                    'openid.mode' => 'checkid_setup'
+                    'openid.mode' => 'checkid_setup',
                     );
+
+                if ( count( $this->requestedData ) > 0 )
+                {
+                    $params['openid.sreg.optional'] = implode( ',', 
$this->requestedData );
+                }
 
                 if ( $this->options->mode === self::MODE_SMART )
                 {
@@ -337,9 +407,13 @@
                        $signed = explode( ',', $signed );
                 for ( $i = 0; $i < count( $signed ); $i++ )
                 {
-                    $s = str_replace( 'sreg_', 'sreg.', $signed[$i] );
-                    $c = $source['openid_' . $signed[$i]];
-                    $params['openid.' . $s] = isset( $params['openid.' . $s] ) 
? $params['openid.' . $s] : $c;
+                    $s = str_replace( 'sreg.', 'sreg_', $signed[$i] );
+                    $c = $source['openid_' . $s];
+                    $params['openid.' . $signed[$i]] = isset( 
$params['openid.' . $s] ) ? $params['openid.' . $s] : $c;
+                    if ( strpos( $s, 'sreg_' ) !== false )
+                    {
+                        $this->data[str_replace( 'sreg_', '', $s )] = array( 
$c );
+                    }
                 }
 
                 if ( isset( $source['openid_op_endpoint'] ) )
@@ -816,5 +890,56 @@
 
         return $result;
     }
+
+    /**
+     * Registers which extra data to fetch during the authentication process.
+     *
+     * The extra data which is possible to be fetched during the authentication
+     * process is:
+     *  - nickname - the user's nickname (short name, alias)
+     *  - email - the user's email address
+     *  - fullname - the user's full name
+     *  - dob - the user's date of birth as YYYY-MM-DD. Any component value 
whose
+     *    representation uses fewer than the specified number of digits should
+     *    be zero-padded (eg. 02 for February). If the user does not want to
+     *    reveal any particular component of this value, it should be zero
+     *    (eg. "1980-00-00" if the user is born in 1980 but does not want to
+     *    specify his month and day of birth)
+     *  - gender - the user's gender, "M" for male, "F" for female
+     *  - postcode - the user's postal code
+     *  - country - the user's country as an ISO3166 string, (eg. "US")
+     *  - language - the user's preferred language as an ISO639 string (eg. 
"FR")
+     *  - timezone - the user's timezone, for example "Europe/Paris"
+     *
+     * The input $data should be an array of attributes to request, for 
example:
+     * <code>
+     * array( 'fullname', 'gender', 'country', 'language' );
+     * </code>
+     *
+     * @param array(string) A list of attributes to fetch during authentication
+     */
+    public function registerFetchData( array $data = array() )
+    {
+        $this->requestedData = $data;
+    }
+
+    /**
+     * Returns the extra data fetched during the authentication process.
+     *
+     * The return is something like:
+     * <code>
+     * array( 'fullname' => array( 'John Doe' ),
+     *        'gender' => array( 'M' ),
+     *        'country' => array( 'US' ),
+     *        'language' => array( 'FR' )
+     *      );
+     * </code>
+     *
+     * @param array(string=>mixed)
+     */
+    public function fetchData()
+    {
+        return $this->data;
+    }
 }
 ?>

Modified: trunk/Authentication/src/filters/typekey/typekey_filter.php
==============================================================================
--- trunk/Authentication/src/filters/typekey/typekey_filter.php [iso-8859-1] 
(original)
+++ trunk/Authentication/src/filters/typekey/typekey_filter.php [iso-8859-1] 
Wed Aug  8 16:41:23 2007
@@ -33,7 +33,10 @@
  *
  * The login link can also contain these 2 optional values:
  *   v = TypeKey version to use. Default is 1.
- *   need_email = the mail address which was used to register with TypeKey.
+ *   need_email = the mail address which was used to register with TypeKey. It
+ *                needs to be set to a value different than 0 in order to get
+ *                the email address of the user when calling fetchData() after
+ *                the authentication process has been completed.
  *
  * So the TypeKey authentication filter will run in the _return page and will
  * verify the signature and the other information in the URL.
@@ -151,6 +154,35 @@
  * ?>
  * </code>
  *
+ * Extra data can be fetched from the TypeKey server during the authentication
+ * process. Different from the other filters, for TypeKey there is no 
registration
+ * needed for fetching the extra data, because all the possible extra data is
+ * available in the response sent by the TypeKey server.
+ *
+ * To be able to get the email address of the user, need_email must be set
+ * to a value different than 0 in the initial request sent to the TypeKey
+ * server (along with the t and _return values). Example:
+ * <code>
+ * https://www.typekey.com/t/typekey/login?t=<token>&_return=<url>&need_email=1
+ * </code>
+ *
+ * Example of fetching the extra data after the initial request has been sent:
+ * <code>
+ * // after run()
+ * // $filter is an ezcAuthenticationTypekeyFilter object
+ * $data = $filter->fetchData();
+ * </code>
+ *
+ * The $data array contains name (TypeKey username), nick (TypeKey display 
name)
+ * and optionally email (if the user allowed the sharing of his email address
+ * in the TypeKey profile page; otherwise it is not set).
+ * <code>
+ * array( 'name' => array( 'john' ),
+ *        'nick' => array( 'John Doe' ),
+ *        'email' => array( '[EMAIL PROTECTED]' ) // or not set
+ *      );
+ * </code>
+ *
  * @property ezcAuthenticationBignumLibrary $lib
  *           The wrapper for the PHP extension to use for big number 
operations.
  *           This will be autodetected in the constructor, but you can specify
@@ -160,7 +192,7 @@
  * @version //autogen//
  * @mainclass
  */
-class ezcAuthenticationTypekeyFilter extends ezcAuthenticationFilter
+class ezcAuthenticationTypekeyFilter extends ezcAuthenticationFilter 
implements ezcAuthenticationDataFetch
 {
     /**
      * The request does not contain the needed information (like $_GET['sig']).
@@ -176,6 +208,25 @@
      * Login is outside of the timeframe.
      */
     const STATUS_SIGNATURE_EXPIRED = 3;
+
+    /**
+     * Holds the extra data fetched during the authentication process.
+     *
+     * Contains name (TypeKey username), nick (TypeKey display name) and
+     * optionally email (if the user allowed the sharing of his email address
+     * in the TypeKey profile page; otherwise it is not set).
+     *
+     * Usually it has this structure:
+     * <code>
+     * array( 'name' => array( 'john' ),
+     *        'nick' => array( 'John Doe' ),
+     *        'email' => array( '[EMAIL PROTECTED]' ) // or not set
+     *      );
+     * </code>
+     *
+     * @var array(string=>mixed)
+     */
+    protected $data = array();
 
     /**
      * Holds the properties of this class.
@@ -287,6 +338,14 @@
             $nick = isset( $source['nick'] ) ? $source['nick'] : null;
             $timestamp = isset( $source['ts'] ) ? $source['ts'] : null;
             $signature = isset( $source['sig'] ) ? $source['sig'] : null;
+
+            // extra data which will be returned by fetchData()
+            $this->data['name'] = array( $id );
+            $this->data['nick'] = array( $nick );
+            if ( strpos( $mail, '@' ) !== false )
+            {
+                $this->data['email'] = array( $mail );
+            }
         }
         else
         {
@@ -381,5 +440,47 @@
         }
         return $keys;
     }
+
+    /**
+     * Registers the extra data which will be fetched by the filter during the
+     * authentication process.
+     *
+     * For TypeKey there is no registration needed, because all the possible
+     * extra data is available in the response sent by the TypeKey server. So
+     * a call to this function is not needed.
+     *
+     * To be able to get the email address of the user, need_email must be set
+     * to a value different than 0 in the initial request sent to the TypeKey
+     * server (along with the t and _return values).
+     *
+     * @param array(string) $data A list of attributes to fetch during 
authentication
+     */
+    public function registerFetchData( array $data = array() )
+    {
+    }
+
+    /**
+     * Returns the extra data which was fetched during the authentication 
process.
+     *
+     * The TypeKey extra data is an array containing the values for name (the
+     * TypeKey username), nick (the TypeKey display name) and email (the email
+     * address of the user, fetched only if the initial request to the TypeKey
+     * server contains need_email, and the user allowed the sharing of his 
email
+     * address).
+     *
+     * Example of returned array:
+     * <code>
+     * array( 'name' => array( 'john' ),
+     *        'nick' => array( 'John Doe' ),
+     *        'email' => array( '[EMAIL PROTECTED]' ) // or not set
+     *      );
+     * </code>
+     *
+     * @return array(string=>mixed)
+     */
+    public function fetchData()
+    {
+        return $this->data;
+    }
 }
 ?>

Added: trunk/Authentication/src/interfaces/data_fetch.php
==============================================================================
--- trunk/Authentication/src/interfaces/data_fetch.php (added)
+++ trunk/Authentication/src/interfaces/data_fetch.php [iso-8859-1] Wed Aug  8 
16:41:23 2007
@@ -1,0 +1,59 @@
+<?php
+/**
+ * File containing the ezcAuthenticationDataFetch interface.
+ *
+ * @copyright Copyright (C) 2005-2007 eZ systems as. All rights reserved.
+ * @license http://ez.no/licenses/new_bsd New BSD License
+ * @filesource
+ * @package Authentication
+ * @version //autogen//
+ */
+
+/**
+ * Interface defining functionality for fetching extra data during the
+ * authentication process.
+ *
+ * Authentication filters which support fetching additional data during
+ * the authentication process can implement this interface.
+ *
+ * @package Authentication
+ * @version //autogen//
+ */
+interface ezcAuthenticationDataFetch
+{
+    /**
+     * Registers which extra data to fetch during the authentication process.
+     *
+     * The input $data should be an array of attributes to request, for 
example:
+     * <code>
+     * array( 'name', 'company', 'mobile' );
+     * </code>
+     *
+     * The extra data that is possible to return depends on the authentication
+     * filter. Please read the description of each filter to find out what 
extra
+     * data is possible to fetch.
+     *
+     * @param array(string) A list of attributes to fetch during authentication
+     */
+    public function registerFetchData( array $data = array() );
+
+    /**
+     * Returns the extra data fetched during the authentication process.
+     *
+     * The return is something like this:
+     * <code>
+     * array( 'name' = > array( 'Dr. No' ),
+     *        'company' => array( 'SPECTRE' ),
+     *        'mobile' => array( '555-7732873' )
+     *      );
+     * </code>
+     *
+     * The extra data that is possible to return depends on the authentication
+     * filter. Please read the description of each filter to find out what 
extra
+     * data is possible to fetch.
+     *
+     * @param array(string=>mixed)
+     */
+    public function fetchData();
+}
+?>

Propchange: trunk/Authentication/src/interfaces/data_fetch.php
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/Authentication/tests/filters/ldap/ldap_test.php
==============================================================================
--- trunk/Authentication/tests/filters/ldap/ldap_test.php [iso-8859-1] 
(original)
+++ trunk/Authentication/tests/filters/ldap/ldap_test.php [iso-8859-1] Wed Aug  
8 16:41:23 2007
@@ -275,6 +275,36 @@
         }
     }
 
+    public function testLdapFetchExtraData()
+    {
+        $credentials = new ezcAuthenticationPasswordCredentials( 'jan.modaal', 
'qwerty' );
+        $ldap = new ezcAuthenticationLdapInfo( self::$host, self::$format, 
self::$base, self::$port );
+        $authentication = new ezcAuthentication( $credentials );
+        $filter = new ezcAuthenticationLdapFilter( $ldap );
+        $filter->registerFetchData( array( 'uid' ) );
+        $authentication->addFilter( $filter );
+        $this->assertEquals( true, $authentication->run() );
+
+        $expected = array( 'uid' => array( 'jan.modaal' ) );
+        $this->assertEquals( $expected, $filter->fetchData() );
+    }
+
+    public function testLdapFetchExtraDataObjectClass()
+    {
+        $credentials = new ezcAuthenticationPasswordCredentials( 'jan.modaal', 
'qwerty' );
+        $ldap = new ezcAuthenticationLdapInfo( self::$host, self::$format, 
self::$base, self::$port );
+        $authentication = new ezcAuthentication( $credentials );
+        $filter = new ezcAuthenticationLdapFilter( $ldap );
+        $filter->registerFetchData( array( 'uid', 'objectclass' ) );
+        $authentication->addFilter( $filter );
+        $this->assertEquals( true, $authentication->run() );
+
+        $expected = array( 'uid' => array( 'jan.modaal' ),
+                           'objectclass' => array( 'account', 
'simpleSecurityObject', 'top' )
+                         );
+        $this->assertEquals( $expected, $filter->fetchData() );
+    }
+
     public function testLdapInfo()
     {
         $ldap = ezcAuthenticationLdapInfo::__set_state( array( 'host' => 
self::$host, 'format' => self::$format, 'base' => self::$base, 'port' => 
self::$port, 'protocol' => ezcAuthenticationLdapFilter::PROTOCOL_TLS ) );

Modified: trunk/Authentication/tests/filters/openid/openid_test.php
==============================================================================
--- trunk/Authentication/tests/filters/openid/openid_test.php [iso-8859-1] 
(original)
+++ trunk/Authentication/tests/filters/openid/openid_test.php [iso-8859-1] Wed 
Aug  8 16:41:23 2007
@@ -44,7 +44,21 @@
         'openid_return_to' => 'http://localhost',
         'openid_identity' => 'http://ezc.myopenid.com',
         'openid_op_endpoint' => 'http://www.myopenid.com/server',
+        'openid_mode' => 'check_authentication'
+        );
+
+    public static $requestCheckAuthenticationGetExtraData = array(
+        'openid_assoc_handle' => '{HMAC-SHA1}{4640581a}{3X/rrw==}',
+        'openid_signed' => 
'return_to,mode,identity,sreg.fullname,sreg.gender,sreg.country,sreg.language',
+        'openid_sig' => 'SkaCB2FA9EysKoDkybyBD46zb0E=',
+        'openid_return_to' => 'http://localhost',
+        'openid_identity' => 'http://ezc.myopenid.com',
+        'openid_op_endpoint' => 'http://www.myopenid.com/server',
         'openid_mode' => 'check_authentication',
+        'openid_sreg_fullname' => 'John Doe',
+        'openid_sreg_gender' => 'M',
+        'openid_sreg_country' => 'US',
+        'openid_sreg_language' => 'FR'
         );
 
     public static $requestCheckAuthenticationGetNoEndPoint = array(
@@ -150,6 +164,29 @@
         }
     }
 
+    public function testOpenidCliExceptionRegisterFetchData()
+    {
+        $credentials = new ezcAuthenticationIdCredentials( self::$url );
+        $authentication = new ezcAuthentication( $credentials );
+        $filter = new ezcAuthenticationOpenidFilter();
+        $filter->registerFetchData( array( 'fullname', 'gender', 'country', 
'language' ) );
+        $authentication->addFilter( $filter );
+
+        try
+        {
+            $authentication->run();
+            $this->fail( "Expected exception was not thrown." );
+        }
+        catch ( ezcAuthenticationOpenidException $e )
+        {
+            $result = $e->getMessage();
+            $expected = "Could not redirect to 
'http://www.myopenid.com/server?openid.return_to=http%3A%2F%2Flocalhost%2Fopenid.php%3Faction%3Dlogin%26openid_identifier%3Dhttp%253A%252F%252Fezc.myopenid.com%26nonce%3D859610&openid.trust_root=http%3A%2F%2Flocalhost&openid.identity=http%3A%2F%2Fezc.myopenid.com%2F&openid.mode=checkid_setup&openid.sreg.optional=fullname,gender,country,language'.
 Most probably your browser does not support redirection or JavaScript.";
+            //$expected = "Could not redirect to 
'http://www.myopenid.com/server?openid.return_to=http%3A%2F%2Flocalhost%2Fopenid.php%3Faction%3Dlogin%26openid_identifier%3Dhttp%253A%252F%252Fezc.myopenid.com%26nonce%3D859610&openid.trust_root=http%3A%2F%2Flocalhost&openid.identity=http%3A%2F%2Fezc.myopenid.com%2F&openid.mode=checkid_setup'.
 Most probably your browser does not support redirection or JavaScript.";
+            $this->assertEquals( substr( $expected, 0, 192 ), substr( $result, 
0, 192 ) );
+            $this->assertEquals( substr( $expected, 198 ), substr( $result, 
198 ) );
+        }
+    }
+
     public function testOpenidCliExceptionFileStoreNonce()
     {
         $credentials = new ezcAuthenticationIdCredentials( self::$url );
@@ -637,6 +674,44 @@
         $this->assertEquals( 
ezcAuthenticationOpenidFilter::STATUS_SIGNATURE_INCORRECT, $result );
 
         $this->removeTempDir();
+    }
+
+    public function 
testOpenidWrapperRunModeIdResFileStoreNonceValidFetchExtraData()
+    {
+        if ( !ezcBaseFeatures::hasExtensionSupport( 'openssl' ) )
+        {
+            $this->markTestSkipped( 'PHP must be compiled with 
--with-openssl.' );
+        }
+
+        $_GET = self::$requestCheckAuthenticationGetExtraData;
+        $_GET['openid_mode'] = 'id_res';
+        $nonce = '123456';
+        $_GET['openid_return_to'] = ezcAuthenticationUrl::appendQuery( 
$_GET['openid_return_to'], 'nonce', $nonce );
+
+        $path = $this->createTempDir( get_class( $this ) );
+
+        $options = new ezcAuthenticationOpenidOptions();
+        $options->store = new ezcAuthenticationOpenidFileStore( $path );
+        $options->store->storeNonce( $nonce );
+
+        $credentials = new ezcAuthenticationIdCredentials( self::$url );
+
+        $filter = new ezcAuthenticationOpenidWrapper( $options );
+
+        // not necessary at this step (id_res), would have been necessary at 
the previous step (login)
+        $filter->registerFetchData( array( 'fullname', 'gender', 'country', 
'language' ) );
+
+        $result = $filter->run( $credentials );
+        $this->assertEquals( 
ezcAuthenticationOpenidFilter::STATUS_SIGNATURE_INCORRECT, $result );
+
+        $this->removeTempDir();
+
+        $expected = array( 'fullname' => array( 'John Doe' ),
+                           'gender' => array( 'M' ),
+                           'country' => array( 'US' ),
+                           'language' => array( 'FR' )
+                         );
+        $this->assertEquals( $expected, $filter->fetchData() );
     }
 
     public function testOpenidWrapperRunModeIdResFileStoreNonceInvalid()

Modified: trunk/Authentication/tests/filters/typekey/typekey_test.php
==============================================================================
--- trunk/Authentication/tests/filters/typekey/typekey_test.php [iso-8859-1] 
(original)
+++ trunk/Authentication/tests/filters/typekey/typekey_test.php [iso-8859-1] 
Wed Aug  8 16:41:23 2007
@@ -32,6 +32,14 @@
         'sig' => 'RaJ5rx U6tKZvs1dbOGktNxPmzA=:aSNNjdE/ZAuk/GQ7mTiQZe83a6E='
         );
 
+    public static $responseWithEmail = array(
+        'name' => 'ezc',
+        'nick' => 'ezctest',
+        'email' => '[EMAIL PROTECTED]',
+        'ts' => '1186560659',
+        'sig' => 'iJxr041JbZ9jWNo84QPT3EuRjxg=:V4YOiYh7FeTFzRgwDSYLqcE4wKA='
+        );
+
     public static $responseEmpty = array(
         'name' => '',
         'nick' => '',
@@ -265,6 +273,42 @@
         $this->unreadableFileTest( $options, 'keysFile', 'keys_unreadable.txt' 
);
     }
 
+    public function testTypeKeyFetchExtraData()
+    {
+        if ( !ezcBaseFeatures::hasExtensionSupport( 'gmp' ) )
+        {
+            $this->markTestSkipped( 'PHP must be compiled with --with-gmp.' );
+        }
+        $_GET = self::$response;
+        $credentials = new ezcAuthenticationIdCredentials( self::$token );
+        $authentication = new ezcAuthentication( $credentials );
+        $filter = new ezcAuthenticationTypekeyFilter();
+        $filter->lib = ezcAuthenticationMath::createBignumLibrary( 'gmp' );
+        $authentication->addFilter( $filter );
+        $this->assertEquals( true, $authentication->run() );
+
+        $expected = array( 'name' => array( 'ezc' ), 'nick' => array( 
'ezctest' ) );
+        $this->assertEquals( $expected, $filter->fetchData() );
+    }
+
+    public function testTypeKeyFetchExtraDataWithEmail()
+    {
+        if ( !ezcBaseFeatures::hasExtensionSupport( 'gmp' ) )
+        {
+            $this->markTestSkipped( 'PHP must be compiled with --with-gmp.' );
+        }
+        $_GET = self::$responseWithEmail;
+        $credentials = new ezcAuthenticationIdCredentials( self::$token );
+        $authentication = new ezcAuthentication( $credentials );
+        $filter = new ezcAuthenticationTypekeyFilter();
+        $filter->lib = ezcAuthenticationMath::createBignumLibrary( 'gmp' );
+        $authentication->addFilter( $filter );
+        $this->assertEquals( true, $authentication->run() );
+
+        $expected = array( 'name' => array( 'ezc' ), 'nick' => array( 
'ezctest' ), 'email' => array( '[EMAIL PROTECTED]' ) );
+        $this->assertEquals( $expected, $filter->fetchData() );
+    }
+
     public function testTypekeyOptions()
     {
         $options = new ezcAuthenticationTypekeyOptions();


-- 
svn-components mailing list
[email protected]
http://lists.ez.no/mailman/listinfo/svn-components

Reply via email to