/htdocs/oauth/EpiOAuth.php

https://github.com/krillo/bandybot_old · PHP · 233 lines · 190 code · 38 blank · 5 comment · 18 complexity · e7a3792ad75e087864330a8547368c06 MD5 · raw file

  1. <?php
  2. class EpiOAuth
  3. {
  4. public $version = '1.0';
  5. protected $requestTokenUrl;
  6. protected $accessTokenUrl;
  7. protected $authorizeUrl;
  8. protected $consumerKey;
  9. protected $consumerSecret;
  10. protected $token;
  11. protected $tokenSecret;
  12. protected $signatureMethod;
  13. public function getAccessToken()
  14. {
  15. $resp = $this->httpRequest('GET', $this->accessTokenUrl);
  16. return new EpiOAuthResponse($resp);
  17. }
  18. public function getAuthorizationUrl()
  19. {
  20. $retval = "{$this->authorizeUrl}?";
  21. $token = $this->getRequestToken();
  22. return $this->authorizeUrl . '?oauth_token=' . $token->oauth_token;
  23. }
  24. public function getRequestToken()
  25. {
  26. $resp = $this->httpRequest('GET', $this->requestTokenUrl);
  27. return new EpiOAuthResponse($resp);
  28. }
  29. public function httpRequest($method = null, $url = null, $params = null)
  30. {
  31. if(empty($method) || empty($url))
  32. return false;
  33. if(empty($params['oauth_signature']))
  34. $params = $this->prepareParameters($method, $url, $params);
  35. switch($method)
  36. {
  37. case 'GET':
  38. return $this->httpGet($url, $params);
  39. break;
  40. case 'POST':
  41. return $this->httpPost($url, $params);
  42. break;
  43. }
  44. }
  45. public function setToken($token = null, $secret = null)
  46. {
  47. $params = func_get_args();
  48. $this->token = $token;
  49. $this->tokenSecret = $secret;
  50. }
  51. public function encode($string)
  52. {
  53. return rawurlencode(utf8_encode($string));
  54. }
  55. protected function addOAuthHeaders(&$ch, $url, $oauthHeaders)
  56. {
  57. $_h = array('Expect:');
  58. $urlParts = parse_url($url);
  59. $oauth = 'Authorization: OAuth realm="' . $urlParts['path'] . '",';
  60. foreach($oauthHeaders as $name => $value)
  61. {
  62. $oauth .= "{$name}=\"{$value}\",";
  63. }
  64. $_h[] = substr($oauth, 0, -1);
  65. curl_setopt($ch, CURLOPT_HTTPHEADER, $_h);
  66. }
  67. protected function generateNonce()
  68. {
  69. if(isset($this->nonce)) // for unit testing
  70. return $this->nonce;
  71. return md5(uniqid(rand(), true));
  72. }
  73. protected function generateSignature($method = null, $url = null, $params = null)
  74. {
  75. if(empty($method) || empty($url))
  76. return false;
  77. // concatenating
  78. $concatenatedParams = '';
  79. foreach($params as $k => $v)
  80. {
  81. $v = $this->encode($v);
  82. $concatenatedParams .= "{$k}={$v}&";
  83. }
  84. $concatenatedParams = $this->encode(substr($concatenatedParams, 0, -1));
  85. // normalize url
  86. $normalizedUrl = $this->encode($this->normalizeUrl($url));
  87. $method = $this->encode($method); // don't need this but why not?
  88. $signatureBaseString = "{$method}&{$normalizedUrl}&{$concatenatedParams}";
  89. return $this->signString($signatureBaseString);
  90. }
  91. protected function httpGet($url, $params = null)
  92. {
  93. if(count($params['request']) > 0)
  94. {
  95. $url .= '?';
  96. foreach($params['request'] as $k => $v)
  97. {
  98. $url .= "{$k}={$v}&";
  99. }
  100. $url = substr($url, 0, -1);
  101. }
  102. $ch = curl_init($url);
  103. $this->addOAuthHeaders($ch, $url, $params['oauth']);
  104. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  105. $resp = $this->curl->addCurl($ch);
  106. return $resp;
  107. }
  108. protected function httpPost($url, $params = null)
  109. {
  110. $ch = curl_init($url);
  111. $this->addOAuthHeaders($ch, $url, $params['oauth']);
  112. curl_setopt($ch, CURLOPT_POST, 1);
  113. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params['request']));
  114. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  115. $resp = $this->curl->addCurl($ch);
  116. return $resp;
  117. }
  118. protected function normalizeUrl($url = null)
  119. {
  120. $urlParts = parse_url($url);
  121. $scheme = strtolower($urlParts['scheme']);
  122. $host = strtolower($urlParts['host']);
  123. $port = intval($urlParts['port']);
  124. $retval = "{$scheme}://{$host}";
  125. if($port > 0 && ($scheme === 'http' && $port !== 80) || ($scheme === 'https' && $port !== 443))
  126. {
  127. $retval .= ":{$port}";
  128. }
  129. $retval .= $urlParts['path'];
  130. if(!empty($urlParts['query']))
  131. {
  132. $retval .= "?{$urlParts['query']}";
  133. }
  134. return $retval;
  135. }
  136. protected function prepareParameters($method = null, $url = null, $params = null)
  137. {
  138. if(empty($method) || empty($url))
  139. return false;
  140. $oauth['oauth_consumer_key'] = $this->consumerKey;
  141. $oauth['oauth_token'] = $this->token;
  142. $oauth['oauth_nonce'] = $this->generateNonce();
  143. $oauth['oauth_timestamp'] = !isset($this->timestamp) ? time() : $this->timestamp; // for unit test
  144. $oauth['oauth_signature_method'] = $this->signatureMethod;
  145. $oauth['oauth_version'] = $this->version;
  146. // encoding
  147. array_walk($oauth, array($this, 'encode'));
  148. if(is_array($params))
  149. array_walk($params, array($this, 'encode'));
  150. $encodedParams = array_merge($oauth, (array)$params);
  151. // sorting
  152. ksort($encodedParams);
  153. // signing
  154. $oauth['oauth_signature'] = $this->encode($this->generateSignature($method, $url, $encodedParams));
  155. return array('request' => $params, 'oauth' => $oauth);
  156. }
  157. protected function signString($string = null)
  158. {
  159. $retval = false;
  160. switch($this->signatureMethod)
  161. {
  162. case 'HMAC-SHA1':
  163. $key = $this->encode($this->consumerSecret) . '&' . $this->encode($this->tokenSecret);
  164. $retval = base64_encode(hash_hmac('sha1', $string, $key, true));
  165. break;
  166. }
  167. return $retval;
  168. }
  169. public function __construct($consumerKey, $consumerSecret, $signatureMethod='HMAC-SHA1')
  170. {
  171. $this->consumerKey = $consumerKey;
  172. $this->consumerSecret = $consumerSecret;
  173. $this->signatureMethod = $signatureMethod;
  174. $this->curl = EpiCurl::getInstance();
  175. }
  176. }
  177. class EpiOAuthResponse
  178. {
  179. private $__resp;
  180. public function __construct($resp)
  181. {
  182. $this->__resp = $resp;
  183. }
  184. public function __get($name)
  185. {
  186. if($this->__resp->code < 200 || $this->__resp->code > 299)
  187. return false;
  188. parse_str($this->__resp->data, $result);
  189. foreach($result as $k => $v)
  190. {
  191. $this->$k = $v;
  192. }
  193. return $result[$name];
  194. }
  195. }