You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
8.1 KiB

  1. <?php
  2. /**
  3. * Dropbox OAuth
  4. *
  5. * @package Dropbox
  6. * @copyright Copyright (C) 2010 Rooftop Solutions. All rights reserved.
  7. * @author Michael Johansen <michael@taskcamp.com>
  8. * @license http://code.google.com/p/dropbox-php/wiki/License MIT
  9. */
  10. /**
  11. * This class is used to sign all requests to dropbox
  12. *
  13. * This classes use the Zend_Oauth package.
  14. */
  15. class Dropbox_OAuth_Zend extends Dropbox_OAuth {
  16. /**
  17. * OAuth object
  18. *
  19. * @var Zend_Oauth_Consumer
  20. */
  21. protected $oAuth;
  22. /**
  23. * OAuth consumer key
  24. *
  25. * We need to keep this around for later.
  26. *
  27. * @var string
  28. */
  29. protected $consumerKey;
  30. /**
  31. *
  32. * @var Zend_Oauth_Token
  33. */
  34. protected $zend_oauth_token;
  35. /**
  36. * Constructor
  37. *
  38. * @param string $consumerKey
  39. * @param string $consumerSecret
  40. */
  41. public function __construct($consumerKey, $consumerSecret) {
  42. if (!class_exists('Zend_Oauth_Consumer')) {
  43. // We're going to try to load in manually
  44. include 'Zend/Oauth/Consumer.php';
  45. }
  46. if (!class_exists('Zend_Oauth_Consumer'))
  47. throw new Dropbox_Exception('The Zend_Oauth_Consumer class could not be found!');
  48. $this->OAuth = new Zend_Oauth_Consumer(array(
  49. "consumerKey" => $consumerKey,
  50. "consumerSecret" => $consumerSecret,
  51. "requestTokenUrl" => self::URI_REQUEST_TOKEN,
  52. "accessTokenUrl" => self::URI_ACCESS_TOKEN,
  53. "authorizeUrl" => self::URI_AUTHORIZE,
  54. "signatureMethod" => "HMAC-SHA1",
  55. ));
  56. $this->consumerKey = $consumerKey;
  57. }
  58. /**
  59. * Sets the request token and secret.
  60. *
  61. * The tokens can also be passed as an array into the first argument.
  62. * The array must have the elements token and token_secret.
  63. *
  64. * @param string|array $token
  65. * @param string $token_secret
  66. * @return void
  67. */
  68. public function setToken($token, $token_secret = null) {
  69. if (is_a($token, "Zend_Oauth_Token")) {
  70. if (is_a($token, "Zend_Oauth_Token_Access")) {
  71. $this->OAuth->setToken($token);
  72. }
  73. $this->zend_oauth_token = $token;
  74. return parent::setToken($token->getToken(), $token->getTokenSecret());
  75. } elseif (is_string($token) && is_null($token_secret)) {
  76. return $this->setToken(unserialize($token));
  77. } elseif (isset($token['zend_oauth_token'])) {
  78. return $this->setToken(unserialize($token['zend_oauth_token']));
  79. } else {
  80. parent::setToken($token, $token_secret);
  81. return;
  82. }
  83. }
  84. /**
  85. * Fetches a secured oauth url and returns the response body.
  86. *
  87. * @param string $uri
  88. * @param mixed $arguments
  89. * @param string $method
  90. * @param array $httpHeaders
  91. * @return string
  92. */
  93. public function fetch($uri, $arguments = array(), $method = 'GET', $httpHeaders = array()) {
  94. $token = $this->OAuth->getToken();
  95. if (!is_a($token, "Zend_Oauth_Token")) {
  96. if (is_a($this->zend_oauth_token, "Zend_Oauth_Token_Access")) {
  97. $token = $this->zend_oauth_token;
  98. } else {
  99. $token = new Zend_Oauth_Token_Access();
  100. $token->setToken($this->oauth_token);
  101. $token->setTokenSecret($this->oauth_token_secret);
  102. }
  103. }
  104. /* @var $token Zend_Oauth_Token_Access */
  105. $oauthOptions = array(
  106. 'consumerKey' => $this->consumerKey,
  107. 'signatureMethod' => "HMAC-SHA1",
  108. 'consumerSecret' => $this->OAuth->getConsumerSecret(),
  109. );
  110. $config = array("timeout" => 15);
  111. /* @var $consumerRequest Zend_Oauth_Client */
  112. $consumerRequest = $token->getHttpClient($oauthOptions);
  113. $consumerRequest->setMethod($method);
  114. if (is_array($arguments)) {
  115. $consumerRequest->setUri($uri);
  116. if ($method == "GET") {
  117. foreach ($arguments as $param => $value) {
  118. $consumerRequest->setParameterGet($param, $value);
  119. }
  120. } else {
  121. foreach ($arguments as $param => $value) {
  122. $consumerRequest->setParameterPost($param, $value);
  123. }
  124. }
  125. } elseif (is_string($arguments)) {
  126. preg_match("/\?file=(.*)$/i", $uri, $matches);
  127. if (isset($matches[1])) {
  128. $uri = str_replace($matches[0], "", $uri);
  129. $filename = $matches[1];
  130. $uri = Zend_Uri::factory($uri);
  131. $uri->addReplaceQueryParameters(array("file" => $filename));
  132. $consumerRequest->setParameterGet("file", $filename);
  133. }
  134. $consumerRequest->setUri($uri);
  135. $consumerRequest->setRawData($arguments);
  136. } elseif (is_resource($arguments)) {
  137. $consumerRequest->setUri($uri);
  138. /** Placeholder for Oauth streaming support. */
  139. }
  140. if (count($httpHeaders)) {
  141. foreach ($httpHeaders as $k => $v) {
  142. $consumerRequest->setHeaders($k, $v);
  143. }
  144. }
  145. $response = $consumerRequest->request();
  146. $body = Zend_Json::decode($response->getBody());
  147. switch ($response->getStatus()) {
  148. // Not modified
  149. case 304 :
  150. return array(
  151. 'httpStatus' => 304,
  152. 'body' => null,
  153. );
  154. break;
  155. case 403 :
  156. throw new Dropbox_Exception_Forbidden('Forbidden.
  157. This could mean a bad OAuth request, or a file or folder already existing at the target location.
  158. ' . $body["error"] . "\n");
  159. case 404 :
  160. throw new Dropbox_Exception_NotFound('Resource at uri: ' . $uri . ' could not be found. ' .
  161. $body["error"] . "\n");
  162. case 507 :
  163. throw new Dropbox_Exception_OverQuota('This dropbox is full. ' .
  164. $body["error"] . "\n");
  165. }
  166. return array(
  167. 'httpStatus' => $response->getStatus(),
  168. 'body' => $response->getBody(),
  169. );
  170. }
  171. /**
  172. * Requests the OAuth request token.
  173. *
  174. * @return void
  175. */
  176. public function getRequestToken() {
  177. $token = $this->OAuth->getRequestToken();
  178. $this->setToken($token);
  179. return $this->getToken();
  180. }
  181. /**
  182. * Requests the OAuth access tokens.
  183. *
  184. * This method requires the 'unauthorized' request tokens
  185. * and, if successful will set the authorized request tokens.
  186. *
  187. * @return void
  188. */
  189. public function getAccessToken() {
  190. if (is_a($this->zend_oauth_token, "Zend_Oauth_Token_Request")) {
  191. $requestToken = $this->zend_oauth_token;
  192. } else {
  193. $requestToken = new Zend_Oauth_Token_Request();
  194. $requestToken->setToken($this->oauth_token);
  195. $requestToken->setTokenSecret($this->oauth_token_secret);
  196. }
  197. $token = $this->OAuth->getAccessToken($_GET, $requestToken);
  198. $this->setToken($token);
  199. return $this->getToken();
  200. }
  201. /**
  202. * Returns the oauth request tokens as an associative array.
  203. *
  204. * The array will contain the elements 'token' and 'token_secret' and the serialized
  205. * Zend_Oauth_Token object.
  206. *
  207. * @return array
  208. */
  209. public function getToken() {
  210. //$token = $this->OAuth->getToken();
  211. //return serialize($token);
  212. return array(
  213. 'token' => $this->oauth_token,
  214. 'token_secret' => $this->oauth_token_secret,
  215. 'zend_oauth_token' => serialize($this->zend_oauth_token),
  216. );
  217. }
  218. /**
  219. * Returns the authorization url
  220. *
  221. * Overloading Dropbox_OAuth to use the built in functions in Zend_Oauth
  222. *
  223. * @param string $callBack Specify a callback url to automatically redirect the user back
  224. * @return string
  225. */
  226. public function getAuthorizeUrl($callBack = null) {
  227. if ($callBack)
  228. $this->OAuth->setCallbackUrl($callBack);
  229. return $this->OAuth->getRedirectUrl();
  230. }
  231. }