File indexing completed on 2024-12-22 05:36:46

0001 <?php
0002 
0003 /**
0004  * Zend Framework
0005  *
0006  * LICENSE
0007  *
0008  * This source file is subject to the new BSD license that is bundled
0009  * with this package in the file LICENSE.txt.
0010  * It is also available through the world-wide-web at this URL:
0011  * http://framework.zend.com/license/new-bsd
0012  * If you did not receive a copy of the license and are unable to
0013  * obtain it through the world-wide-web, please send an email
0014  * to license@zend.com so we can send you a copy immediately.
0015  *
0016  * @category   Zend
0017  * @package    Zend_Gdata
0018  * @subpackage Gdata
0019  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0020  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0021  * @version    $Id$
0022  */
0023 
0024 /**
0025  * Zend_Gdata_HttpClient
0026  */
0027 // require_once 'Zend/Gdata/HttpClient.php';
0028 
0029 /**
0030  * Zend_Version
0031  */
0032 // require_once 'Zend/Version.php';
0033 
0034 /**
0035  * Class to facilitate Google's "Account Authentication
0036  * for Installed Applications" also known as "ClientLogin".
0037  * @see http://code.google.com/apis/accounts/AuthForInstalledApps.html
0038  *
0039  * @category   Zend
0040  * @package    Zend_Gdata
0041  * @subpackage Gdata
0042  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0043  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0044  */
0045 class Zend_Gdata_ClientLogin
0046 {
0047 
0048     /**
0049      * The Google client login URI
0050      *
0051      */
0052     const CLIENTLOGIN_URI = 'https://www.google.com/accounts/ClientLogin';
0053 
0054     /**
0055      * The default 'source' parameter to send to Google
0056      *
0057      */
0058     const DEFAULT_SOURCE = 'Zend-ZendFramework';
0059 
0060     /**
0061      * Set Google authentication credentials.
0062      * Must be done before trying to do any Google Data operations that
0063      * require authentication.
0064      * For example, viewing private data, or posting or deleting entries.
0065      *
0066      * @param string $email
0067      * @param string $password
0068      * @param string $service
0069      * @param Zend_Gdata_HttpClient $client
0070      * @param string $source
0071      * @param string $loginToken The token identifier as provided by the server.
0072      * @param string $loginCaptcha The user's response to the CAPTCHA challenge.
0073      * @param string $accountType An optional string to identify whether the
0074      * account to be authenticated is a google or a hosted account. Defaults to
0075      * 'HOSTED_OR_GOOGLE'. See: http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html#Request
0076      * @throws Zend_Gdata_App_AuthException
0077      * @throws Zend_Gdata_App_HttpException
0078      * @throws Zend_Gdata_App_CaptchaRequiredException
0079      * @return Zend_Gdata_HttpClient
0080      */
0081     public static function getHttpClient($email, $password, $service = 'xapi',
0082         $client = null,
0083         $source = self::DEFAULT_SOURCE,
0084         $loginToken = null,
0085         $loginCaptcha = null,
0086         $loginUri = self::CLIENTLOGIN_URI,
0087         $accountType = 'HOSTED_OR_GOOGLE')
0088     {
0089         if (! ($email && $password)) {
0090             // require_once 'Zend/Gdata/App/AuthException.php';
0091             throw new Zend_Gdata_App_AuthException(
0092                    'Please set your Google credentials before trying to ' .
0093                    'authenticate');
0094         }
0095 
0096         if ($client == null) {
0097             $client = new Zend_Gdata_HttpClient();
0098         }
0099         if (!$client instanceof Zend_Http_Client) {
0100             // require_once 'Zend/Gdata/App/HttpException.php';
0101             throw new Zend_Gdata_App_HttpException(
0102                     'Client is not an instance of Zend_Http_Client.');
0103         }
0104 
0105         // Build the HTTP client for authentication
0106         $client->setUri($loginUri);
0107         $useragent = $source . ' Zend_Framework_Gdata/' . Zend_Version::VERSION;
0108         $client->setConfig(array(
0109                 'maxredirects'    => 0,
0110                 'strictredirects' => true,
0111                 'useragent' => $useragent
0112             )
0113         );
0114         $client->setParameterPost('accountType', $accountType);
0115         $client->setParameterPost('Email', (string) $email);
0116         $client->setParameterPost('Passwd', (string) $password);
0117         $client->setParameterPost('service', (string) $service);
0118         $client->setParameterPost('source', (string) $source);
0119         if ($loginToken || $loginCaptcha) {
0120             if($loginToken && $loginCaptcha) {
0121                 $client->setParameterPost('logintoken', (string) $loginToken);
0122                 $client->setParameterPost('logincaptcha',
0123                         (string) $loginCaptcha);
0124             }
0125             else {
0126                 // require_once 'Zend/Gdata/App/AuthException.php';
0127                 throw new Zend_Gdata_App_AuthException(
0128                     'Please provide both a token ID and a user\'s response ' .
0129                     'to the CAPTCHA challenge.');
0130             }
0131         }
0132 
0133         // Send the authentication request
0134         // For some reason Google's server causes an SSL error. We use the
0135         // output buffer to supress an error from being shown. Ugly - but works!
0136         ob_start();
0137         try {
0138             $response = $client->request('POST');
0139         } catch (Zend_Http_Client_Exception $e) {
0140             // require_once 'Zend/Gdata/App/HttpException.php';
0141             throw new Zend_Gdata_App_HttpException($e->getMessage(), $e);
0142         }
0143         ob_end_clean();
0144 
0145         // Parse Google's response
0146         $goog_resp = array();
0147         foreach (explode("\n", $response->getBody()) as $l) {
0148             $l = chop($l);
0149             if ($l) {
0150                 list($key, $val) = explode('=', chop($l), 2);
0151                 $goog_resp[$key] = $val;
0152             }
0153         }
0154 
0155         if ($response->getStatus() == 200) {
0156             $client->setClientLoginToken($goog_resp['Auth']);
0157             $useragent = $source . ' Zend_Framework_Gdata/' . Zend_Version::VERSION;
0158             $client->setConfig(array(
0159                     'strictredirects' => true,
0160                     'useragent' => $useragent
0161                 )
0162             );
0163             return $client;
0164 
0165         } elseif ($response->getStatus() == 403) {
0166             // Check if the server asked for a CAPTCHA
0167             if (array_key_exists('Error', $goog_resp) &&
0168                 $goog_resp['Error'] == 'CaptchaRequired') {
0169                 // require_once 'Zend/Gdata/App/CaptchaRequiredException.php';
0170                 throw new Zend_Gdata_App_CaptchaRequiredException(
0171                     $goog_resp['CaptchaToken'], $goog_resp['CaptchaUrl']);
0172             }
0173             else {
0174                 // require_once 'Zend/Gdata/App/AuthException.php';
0175                 throw new Zend_Gdata_App_AuthException('Authentication with Google failed. Reason: ' .
0176                     (isset($goog_resp['Error']) ? $goog_resp['Error'] : 'Unspecified.'));
0177             }
0178         }
0179     }
0180 
0181 }
0182