PageRenderTime 53ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/application/helpers/account/jmathai-twitter-async/EpiOAuth.php

https://gitlab.com/ahsanullah716/auth_master
PHP | 422 lines | 346 code | 62 blank | 14 comment | 47 complexity | bbf63ba22ff91f91bb83771646236c45 MD5 | raw file
  1. <?php
  2. class EpiOAuth {
  3. public $version = '1.0';
  4. protected $requestTokenUrl;
  5. protected $accessTokenUrl;
  6. protected $authenticateUrl;
  7. protected $authorizeUrl;
  8. protected $consumerKey;
  9. protected $consumerSecret;
  10. protected $token;
  11. protected $tokenSecret;
  12. protected $callback;
  13. protected $signatureMethod;
  14. protected $debug = FALSE;
  15. protected $useSSL = FALSE;
  16. protected $followLocation = FALSE;
  17. protected $headers = array();
  18. protected $userAgent = 'EpiOAuth (http://github.com/jmathai/twitter-async/tree/)';
  19. protected $connectionTimeout = 5;
  20. protected $requestTimeout = 30;
  21. public function addHeader($header)
  22. {
  23. if (is_array($header) && ! empty($header)) $this->headers = array_merge($this->headers, $header);
  24. elseif ( ! empty($header)) $this->headers[] = $header;
  25. }
  26. public function getAccessToken($params = NULL)
  27. {
  28. if (isset($_GET['oauth_verifier']) && ! isset($params['oauth_verifier']))
  29. {
  30. $params['oauth_verifier'] = $_GET['oauth_verifier'];
  31. }
  32. $resp = $this->httpRequest('POST', $this->getUrl($this->accessTokenUrl), $params);
  33. return new EpiOAuthResponse($resp);
  34. }
  35. public function getAuthenticateUrl($token = NULL, $params = NULL)
  36. {
  37. $token = $token ? $token : $this->getRequestToken($params);
  38. if (is_object($token)) $token = $token->oauth_token;
  39. $addlParams = empty($params) ? '' : '&'.http_build_query($params, '', '&');
  40. return $this->getUrl($this->authenticateUrl).'?oauth_token='.$token.$addlParams;
  41. }
  42. public function getAuthorizeUrl($token = NULL, $params = NULL)
  43. {
  44. $token = $token ? $token : $this->getRequestToken($params);
  45. if (is_object($token)) $token = $token->oauth_token;
  46. return $this->getUrl($this->authorizeUrl).'?oauth_token='.$token;
  47. }
  48. // DEPRECATED in favor of getAuthorizeUrl()
  49. public function getAuthorizationUrl($token = NULL)
  50. {
  51. return $this->getAuthorizeUrl($token);
  52. }
  53. public function getRequestToken($params = NULL)
  54. {
  55. if (isset($this->callback) && ! isset($params['oauth_callback']))
  56. {
  57. $params['oauth_callback'] = $this->callback;
  58. }
  59. $resp = $this->httpRequest('POST', $this->getUrl($this->requestTokenUrl), $params);
  60. return new EpiOAuthResponse($resp);
  61. }
  62. public function getUrl($url)
  63. {
  64. if ($this->useSSL === TRUE) return preg_replace('/^http:/', 'https:', $url);
  65. return $url;
  66. }
  67. public function httpRequest($method = NULL, $url = NULL, $params = NULL, $isMultipart = FALSE)
  68. {
  69. if (empty($method) || empty($url)) return FALSE;
  70. if (empty($params['oauth_signature'])) $params = $this->prepareParameters($method, $url, $params);
  71. switch ($method)
  72. {
  73. case 'GET':
  74. return $this->httpGet($url, $params);
  75. break;
  76. case 'POST':
  77. return $this->httpPost($url, $params, $isMultipart);
  78. break;
  79. case 'DELETE':
  80. return $this->httpDelete($url, $params);
  81. break;
  82. }
  83. }
  84. public function setDebug($bool = FALSE)
  85. {
  86. $this->debug = (bool)$bool;
  87. }
  88. public function setFollowLocation($bool)
  89. {
  90. $this->followLocation = (bool)$bool;
  91. }
  92. public function setTimeout($requestTimeout = NULL, $connectionTimeout = NULL)
  93. {
  94. if ($requestTimeout !== NULL) $this->requestTimeout = floatval($requestTimeout);
  95. if ($connectionTimeout !== NULL) $this->connectionTimeout = floatval($connectionTimeout);
  96. }
  97. public function setToken($token = NULL, $secret = NULL)
  98. {
  99. $this->token = $token;
  100. $this->tokenSecret = $secret;
  101. }
  102. public function setCallback($callback = NULL)
  103. {
  104. $this->callback = $callback;
  105. }
  106. public function useSSL($use = FALSE)
  107. {
  108. $this->useSSL = (bool)$use;
  109. }
  110. protected function addDefaultHeaders($url, $oauthHeaders)
  111. {
  112. $_h = array('Expect:');
  113. $urlParts = parse_url($url);
  114. $oauth = 'Authorization: OAuth realm="'.$urlParts['scheme'].'://'.$urlParts['host'].$urlParts['path'].'",';
  115. foreach ($oauthHeaders as $name => $value)
  116. {
  117. $oauth .= "{$name}=\"{$value}\",";
  118. }
  119. $_h[] = substr($oauth, 0, - 1);
  120. $_h[] = "User-Agent: {$this->userAgent}";
  121. $this->addHeader($_h);
  122. }
  123. protected function buildHttpQueryRaw($params)
  124. {
  125. $retval = '';
  126. foreach ((array)$params as $key => $value) $retval .= "{$key}={$value}&";
  127. $retval = substr($retval, 0, - 1);
  128. return $retval;
  129. }
  130. protected function curlInit($url)
  131. {
  132. $ch = curl_init($url);
  133. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  134. curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
  135. curl_setopt($ch, CURLOPT_TIMEOUT, $this->requestTimeout);
  136. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->connectionTimeout);
  137. curl_setopt($ch, CURLOPT_ENCODING, '');
  138. if ($this->followLocation) curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
  139. if (isset($_SERVER ['SERVER_ADDR']) && ! empty($_SERVER['SERVER_ADDR']) && $_SERVER['SERVER_ADDR'] != '127.0.0.1') curl_setopt($ch, CURLOPT_INTERFACE, $_SERVER ['SERVER_ADDR']);
  140. // if the certificate exists then use it, else bypass ssl checks
  141. if (file_exists($cert = dirname(__FILE__).DIRECTORY_SEPARATOR.'ca-bundle.crt'))
  142. {
  143. curl_setopt($ch, CURLOPT_CAINFO, $cert);
  144. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
  145. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  146. }
  147. else
  148. {
  149. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  150. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  151. }
  152. return $ch;
  153. }
  154. protected function emptyHeaders()
  155. {
  156. $this->headers = array();
  157. }
  158. protected function encode_rfc3986($string)
  159. {
  160. return str_replace('+', ' ', str_replace('%7E', '~', rawurlencode(($string))));
  161. }
  162. protected function generateNonce()
  163. {
  164. if (isset($this->nonce)) // for unit testing
  165. return $this->nonce;
  166. return md5(uniqid(rand(), TRUE));
  167. }
  168. // parameters should already have been passed through prepareParameters
  169. // no need to double encode
  170. protected function generateSignature($method = NULL, $url = NULL, $params = NULL)
  171. {
  172. if (empty($method) || empty($url)) return FALSE;
  173. // concatenating and encode
  174. $concatenatedParams = $this->encode_rfc3986($this->buildHttpQueryRaw($params));
  175. // normalize url
  176. $normalizedUrl = $this->encode_rfc3986($this->normalizeUrl($url));
  177. $method = $this->encode_rfc3986($method); // don't need this but why not?
  178. $signatureBaseString = "{$method}&{$normalizedUrl}&{$concatenatedParams}";
  179. return $this->signString($signatureBaseString);
  180. }
  181. protected function executeCurl($ch)
  182. {
  183. if ($this->isAsynchronous) return $this->curl->addCurl($ch);
  184. else
  185. return $this->curl->addEasyCurl($ch);
  186. }
  187. protected function httpDelete($url, $params)
  188. {
  189. $this->addDefaultHeaders($url, $params['oauth']);
  190. $ch = $this->curlInit($url);
  191. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
  192. curl_setopt($ch, CURLOPT_POSTFIELDS, $this->buildHttpQueryRaw($params['request']));
  193. $resp = $this->executeCurl($ch);
  194. $this->emptyHeaders();
  195. return $resp;
  196. }
  197. protected function httpGet($url, $params = NULL)
  198. {
  199. if (count($params['request']) > 0)
  200. {
  201. $url .= '?';
  202. foreach ($params['request'] as $k => $v)
  203. {
  204. $url .= "{$k}={$v}&";
  205. }
  206. $url = substr($url, 0, - 1);
  207. }
  208. $this->addDefaultHeaders($url, $params['oauth']);
  209. $ch = $this->curlInit($url);
  210. $resp = $this->executeCurl($ch);
  211. $this->emptyHeaders();
  212. return $resp;
  213. }
  214. protected function httpPost($url, $params = NULL, $isMultipart)
  215. {
  216. $this->addDefaultHeaders($url, $params['oauth']);
  217. $ch = $this->curlInit($url);
  218. curl_setopt($ch, CURLOPT_POST, 1);
  219. // php's curl extension automatically sets the content type
  220. // based on whether the params are in string or array form
  221. if ($isMultipart) curl_setopt($ch, CURLOPT_POSTFIELDS, $params['request']);
  222. else
  223. curl_setopt($ch, CURLOPT_POSTFIELDS, $this->buildHttpQueryRaw($params['request']));
  224. $resp = $this->executeCurl($ch);
  225. $this->emptyHeaders();
  226. return $resp;
  227. }
  228. protected function normalizeUrl($url = NULL)
  229. {
  230. $urlParts = parse_url($url);
  231. $scheme = strtolower($urlParts['scheme']);
  232. $host = strtolower($urlParts['host']);
  233. $port = isset($urlParts['port']) ? intval($urlParts['port']) : 0;
  234. $retval = strtolower($scheme).'://'.strtolower($host);
  235. if ( ! empty($port) && (($scheme === 'http' && $port != 80) || ($scheme === 'https' && $port != 443))) $retval .= ":{$port}";
  236. $retval .= $urlParts['path'];
  237. if ( ! empty($urlParts['query']))
  238. {
  239. $retval .= "?{$urlParts['query']}";
  240. }
  241. return $retval;
  242. }
  243. protected function isMultipart($params = NULL)
  244. {
  245. if ($params)
  246. {
  247. foreach ($params as $k => $v)
  248. {
  249. if (strncmp('@', $k, 1) === 0) return TRUE;
  250. }
  251. }
  252. return FALSE;
  253. }
  254. protected function prepareParameters($method = NULL, $url = NULL, $params = NULL)
  255. {
  256. if (empty($method) || empty($url)) return FALSE;
  257. $oauth['oauth_consumer_key'] = $this->consumerKey;
  258. $oauth['oauth_token'] = $this->token;
  259. $oauth['oauth_nonce'] = $this->generateNonce();
  260. $oauth['oauth_timestamp'] = ! isset($this->timestamp) ? time() : $this->timestamp; // for unit test
  261. $oauth['oauth_signature_method'] = $this->signatureMethod;
  262. if (isset($params['oauth_verifier']))
  263. {
  264. $oauth['oauth_verifier'] = $params['oauth_verifier'];
  265. unset($params['oauth_verifier']);
  266. }
  267. $oauth['oauth_version'] = $this->version;
  268. // encode all oauth values
  269. foreach ($oauth as $k => $v) $oauth[$k] = $this->encode_rfc3986($v);
  270. // encode all non '@' params
  271. // keep sigParams for signature generation (exclude '@' params)
  272. // rename '@key' to 'key'
  273. $sigParams = array();
  274. $hasFile = FALSE;
  275. if (is_array($params))
  276. {
  277. foreach ($params as $k => $v)
  278. {
  279. if (strncmp('@', $k, 1) !== 0)
  280. {
  281. $sigParams[$k] = $this->encode_rfc3986($v);
  282. $params[$k] = $this->encode_rfc3986($v);
  283. }
  284. else
  285. {
  286. $params[substr($k, 1)] = $v;
  287. unset($params[$k]);
  288. $hasFile = TRUE;
  289. }
  290. }
  291. if ($hasFile === TRUE) $sigParams = array();
  292. }
  293. $sigParams = array_merge($oauth, (array)$sigParams);
  294. // sorting
  295. ksort($sigParams);
  296. // signing
  297. $oauth['oauth_signature'] = $this->encode_rfc3986($this->generateSignature($method, $url, $sigParams));
  298. return array('request' => $params, 'oauth' => $oauth);
  299. }
  300. protected function signString($string = NULL)
  301. {
  302. $retval = FALSE;
  303. switch ($this->signatureMethod)
  304. {
  305. case 'HMAC-SHA1':
  306. $key = $this->encode_rfc3986($this->consumerSecret).'&'.$this->encode_rfc3986($this->tokenSecret);
  307. $retval = base64_encode(hash_hmac('sha1', $string, $key, TRUE));
  308. break;
  309. }
  310. return $retval;
  311. }
  312. public function __construct($consumerKey, $consumerSecret, $signatureMethod = 'HMAC-SHA1')
  313. {
  314. $this->consumerKey = $consumerKey;
  315. $this->consumerSecret = $consumerSecret;
  316. $this->signatureMethod = $signatureMethod;
  317. $this->curl = EpiCurl::getInstance();
  318. }
  319. }
  320. class EpiOAuthResponse {
  321. private $__resp;
  322. protected $debug = FALSE;
  323. public function __construct($resp)
  324. {
  325. $this->__resp = $resp;
  326. }
  327. public function __get($name)
  328. {
  329. if ($this->__resp->code != 200) EpiOAuthException::raise($this->__resp, $this->debug);
  330. parse_str($this->__resp->data, $result);
  331. foreach ($result as $k => $v)
  332. {
  333. $this->$k = $v;
  334. }
  335. return isset($result[$name]) ? $result[$name] : NULL;
  336. }
  337. public function __toString()
  338. {
  339. return $this->__resp->data;
  340. }
  341. }
  342. class EpiOAuthException extends Exception {
  343. public static function raise($response, $debug)
  344. {
  345. $message = $response->responseText;
  346. switch ($response->code)
  347. {
  348. case 400:
  349. throw new EpiOAuthBadRequestException($message, $response->code);
  350. case 401:
  351. throw new EpiOAuthUnauthorizedException($message, $response->code);
  352. default:
  353. throw new EpiOAuthException($message, $response->code);
  354. }
  355. }
  356. }
  357. class EpiOAuthBadRequestException extends EpiOAuthException {
  358. }
  359. class EpiOAuthUnauthorizedException extends EpiOAuthException {
  360. }