2
0

ClientLogin.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Gdata
  17. * @subpackage Gdata
  18. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. /**
  22. * Zend_Gdata_HttpClient
  23. */
  24. require_once 'Zend/Gdata/HttpClient.php';
  25. /**
  26. * Zend_Version
  27. */
  28. require_once 'Zend/Version.php';
  29. /**
  30. * Class to facilitate Google's "Account Authentication
  31. * for Installed Applications" also known as "ClientLogin".
  32. * @see http://code.google.com/apis/accounts/AuthForInstalledApps.html
  33. *
  34. * @category Zend
  35. * @package Zend_Gdata
  36. * @subpackage Gdata
  37. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  38. * @license http://framework.zend.com/license/new-bsd New BSD License
  39. */
  40. class Zend_Gdata_ClientLogin
  41. {
  42. /**
  43. * The Google client login URI
  44. *
  45. */
  46. const CLIENTLOGIN_URI = 'https://www.google.com/accounts/ClientLogin';
  47. /**
  48. * The default 'source' parameter to send to Google
  49. *
  50. */
  51. const DEFAULT_SOURCE = 'Zend-ZendFramework';
  52. /**
  53. * Set Google authentication credentials.
  54. * Must be done before trying to do any Google Data operations that
  55. * require authentication.
  56. * For example, viewing private data, or posting or deleting entries.
  57. *
  58. * @param string $email
  59. * @param string $password
  60. * @param string $service
  61. * @param Zend_Gdata_HttpClient $client
  62. * @param string $source
  63. * @param string $loginToken The token identifier as provided by the server.
  64. * @param string $loginCaptcha The user's response to the CAPTCHA challenge.
  65. * @param string $accountType An optional string to identify whether the
  66. * account to be authenticated is a google or a hosted account. Defaults to
  67. * 'HOSTED_OR_GOOGLE'. See: http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html#Request
  68. * @throws Zend_Gdata_App_AuthException
  69. * @throws Zend_Gdata_App_HttpException
  70. * @throws Zend_Gdata_App_CaptchaRequiredException
  71. * @return Zend_Gdata_HttpClient
  72. */
  73. public static function getHttpClient($email, $password, $service = 'xapi',
  74. $client = null,
  75. $source = self::DEFAULT_SOURCE,
  76. $loginToken = null,
  77. $loginCaptcha = null,
  78. $loginUri = self::CLIENTLOGIN_URI,
  79. $accountType = 'HOSTED_OR_GOOGLE')
  80. {
  81. if (! ($email && $password)) {
  82. require_once 'Zend/Gdata/App/AuthException.php';
  83. throw new Zend_Gdata_App_AuthException(
  84. 'Please set your Google credentials before trying to ' .
  85. 'authenticate');
  86. }
  87. if ($client == null) {
  88. $client = new Zend_Gdata_HttpClient();
  89. }
  90. if (!$client instanceof Zend_Http_Client) {
  91. require_once 'Zend/Gdata/App/HttpException.php';
  92. throw new Zend_Gdata_App_HttpException(
  93. 'Client is not an instance of Zend_Http_Client.');
  94. }
  95. // Build the HTTP client for authentication
  96. $client->setUri($loginUri);
  97. $useragent = $source . ' Zend_Framework_Gdata/' . Zend_Version::VERSION;
  98. $client->setConfig(array(
  99. 'maxredirects' => 0,
  100. 'strictredirects' => true,
  101. 'useragent' => $useragent
  102. )
  103. );
  104. $client->setParameterPost('accountType', $accountType);
  105. $client->setParameterPost('Email', (string) $email);
  106. $client->setParameterPost('Passwd', (string) $password);
  107. $client->setParameterPost('service', (string) $service);
  108. $client->setParameterPost('source', (string) $source);
  109. if ($loginToken || $loginCaptcha) {
  110. if($loginToken && $loginCaptcha) {
  111. $client->setParameterPost('logintoken', (string) $loginToken);
  112. $client->setParameterPost('logincaptcha',
  113. (string) $loginCaptcha);
  114. }
  115. else {
  116. require_once 'Zend/Gdata/App/AuthException.php';
  117. throw new Zend_Gdata_App_AuthException(
  118. 'Please provide both a token ID and a user\'s response ' .
  119. 'to the CAPTCHA challenge.');
  120. }
  121. }
  122. // Send the authentication request
  123. // For some reason Google's server causes an SSL error. We use the
  124. // output buffer to supress an error from being shown. Ugly - but works!
  125. ob_start();
  126. try {
  127. $response = $client->request('POST');
  128. } catch (Zend_Http_Client_Exception $e) {
  129. require_once 'Zend/Gdata/App/HttpException.php';
  130. throw new Zend_Gdata_App_HttpException($e->getMessage(), $e);
  131. }
  132. ob_end_clean();
  133. // Parse Google's response
  134. $goog_resp = array();
  135. foreach (explode("\n", $response->getBody()) as $l) {
  136. $l = chop($l);
  137. if ($l) {
  138. list($key, $val) = explode('=', chop($l), 2);
  139. $goog_resp[$key] = $val;
  140. }
  141. }
  142. if ($response->getStatus() == 200) {
  143. $client->setClientLoginToken($goog_resp['Auth']);
  144. $useragent = $source . ' Zend_Framework_Gdata/' . Zend_Version::VERSION;
  145. $client->setConfig(array(
  146. 'strictredirects' => true,
  147. 'useragent' => $useragent
  148. )
  149. );
  150. return $client;
  151. } elseif ($response->getStatus() == 403) {
  152. // Check if the server asked for a CAPTCHA
  153. if (array_key_exists('Error', $goog_resp) &&
  154. $goog_resp['Error'] == 'CaptchaRequired') {
  155. require_once 'Zend/Gdata/App/CaptchaRequiredException.php';
  156. throw new Zend_Gdata_App_CaptchaRequiredException(
  157. $goog_resp['CaptchaToken'], $goog_resp['CaptchaUrl']);
  158. }
  159. else {
  160. require_once 'Zend/Gdata/App/AuthException.php';
  161. throw new Zend_Gdata_App_AuthException('Authentication with Google failed. Reason: ' .
  162. (isset($goog_resp['Error']) ? $goog_resp['Error'] : 'Unspecified.'));
  163. }
  164. }
  165. }
  166. }