OAuth.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. <?php
  2. /**
  3. * [Discuz!] (C)2001-2099 Comsenz Inc.
  4. * This is NOT a freeware, use is subject to license terms
  5. *
  6. * $Id: OAuth.php 33542 2013-07-03 05:15:00Z nemohou $
  7. */
  8. if(!defined('IN_DISCUZ')) {
  9. exit('Access Denied');
  10. }
  11. class Cloud_Service_Client_OAuth {
  12. protected $_appKey = '';
  13. protected $_appSecret = '';
  14. protected $_apiIp = '';
  15. private $_tokenSecret = '';
  16. private $_boundary = '';
  17. const OAUTH_VERSION = '1.0';
  18. const OAUTH_SIGNATURE_METHOD = 'HMAC-SHA1';
  19. protected static $_instance;
  20. public static function getInstance() {
  21. if (!(self::$_instance instanceof self)) {
  22. self::$_instance = new self();
  23. }
  24. return self::$_instance;
  25. }
  26. public function dfsockopen($requestURL, $queryString = array(), $files = false) {
  27. return dfsockopen($requestURL, 0, $queryString, '', false, $this->_apiIp, 15, TRUE, !$files ? 'URLENCODE' : 'FORMDATA', true, 0, $files);
  28. }
  29. public function callback($response) {
  30. if(strpos($response, "callback") === false) {
  31. return array();
  32. }
  33. $lpos = strpos($response, "(");
  34. $rpos = strrpos($response, ")");
  35. $response = substr($response, $lpos + 1, $rpos - $lpos - 1);
  36. return json_decode($response);
  37. }
  38. public function getRequest($requestURL, $extra = array(), $oauthMethod = 'GET', $multi = array()) {
  39. if($multi) {
  40. $imageFile = $this->_getImageBinary($multi);
  41. $extra = array_merge($extra, $imageFile['binary']);
  42. }
  43. $params = $this->_getOAuthSignatureParams($extra);
  44. $params['oauth_signature'] = $this->_getOAuthSignature($requestURL, $params, $oauthMethod, $multi ? TRUE : FALSE);
  45. $queryString = $this->_httpBuildQuery($params, $imageFile['fileInfo']);
  46. if($oauthMethod == 'GET') {
  47. $requestURL = $requestURL.'?'.$queryString;
  48. $queryString = '';
  49. } else {
  50. $requestURL = $requestURL.'?';
  51. }
  52. return $this->dfsockopen($requestURL, $queryString, $multi);
  53. }
  54. public function getTimestamp() {
  55. return time();
  56. }
  57. public function getOAuthNonce() {
  58. return time().(time() % $this->_appKey);
  59. }
  60. protected function setAppKey($appKey, $appSecret) {
  61. $this->_appKey = $appKey;
  62. $this->_appSecret = $appSecret;
  63. }
  64. protected function setTokenSecret($tokenSecret) {
  65. $this->_tokenSecret = $tokenSecret;
  66. }
  67. protected function setApiIp($apiIp) {
  68. $this->_apiIp = $apiIp;
  69. }
  70. public function customHmac($str, $key) {
  71. $utilService = Cloud::loadClass('Service_Util');
  72. return base64_encode($utilService->hashHmac('sha1', $str, $key, true));
  73. }
  74. private function _getOAuthSignatureParams($extra = array()) {
  75. $params = array(
  76. 'oauth_consumer_key' => $this->_appKey,
  77. 'oauth_nonce' => $this->getOAuthNonce(),
  78. 'oauth_signature_method' => self::OAUTH_SIGNATURE_METHOD,
  79. 'oauth_timestamp' => $this->getTimestamp(),
  80. 'oauth_version' => self::OAUTH_VERSION,
  81. );
  82. if($extra) {
  83. $params = array_merge($params, $extra);
  84. }
  85. uksort($params, 'strcmp');
  86. return $params;
  87. }
  88. private function _httpBuildQuery($params, $multi = array()) {
  89. if(!$params) {
  90. return '';
  91. }
  92. $multiPartBody = '';
  93. if($multi) {
  94. $this->_boundary = uniqid('------------------');
  95. $bodyBoundary = '--'.$this->_boundary;
  96. $endBodyBoundary = $bodyBoundary.'--';
  97. foreach($params as $param => $value) {
  98. if(array_key_exists($param, $multi)) {
  99. $ext = strtolower(substr(strrchr($multi[$param]['file'], '.'), 1, 10));
  100. $fileName = 'picture.'.$ext;
  101. $mime = $multi[$param]['mime'];
  102. $multiPartBody .= $bodyBoundary."\r\n";
  103. $multiPartBody .= 'Content-Disposition: form-data; name="'.$param.'"; filename="'.$fileName.'"'."\r\n";
  104. $multiPartBody .= 'Content-Type: '.$mime."\r\n\r\n";
  105. $multiPartBody .= $value. "\r\n";
  106. } else {
  107. $multiPartBody .= $bodyBoundary . "\r\n";
  108. $multiPartBody .= 'content-disposition: form-data; name="'.$param."\"\r\n\r\n";
  109. $multiPartBody .= $value."\r\n";
  110. }
  111. }
  112. $multiPartBody .= $endBodyBoundary."\r\n";
  113. } else {
  114. foreach($params as $param => $value) {
  115. $multiPartBody .= $comma.$this->rawurlencode($param).'='.$this->rawurlencode($value);
  116. $comma = '&';
  117. }
  118. }
  119. return $multiPartBody;
  120. }
  121. private function _getOAuthSignature($url, $params, $method = 'POST', $multi = FALSE) {
  122. $method = strtoupper($method);
  123. if(!in_array($method, array ('GET', 'POST'))) {
  124. throw new Exception('Request Method Invlid');
  125. }
  126. if ($params['oauth_callback']) {
  127. $params['oauth_callback'] = rawurlencode($params['oauth_callback']);
  128. }
  129. foreach($params as $name => $val) {
  130. $param_str .= $comma.$name.'='.$val;
  131. $comma = '&';
  132. }
  133. if($multi) {
  134. $base_string = $method.'&'.$url.'&'.$param_str;
  135. } else {
  136. $base_string = $method.'&'.$this->rawurlencode($url).'&'.$this->rawurlencode($param_str);
  137. }
  138. $key = $this->_appSecret.'&'.$this->_tokenSecret;
  139. $signature = $this->customHmac($base_string, $key);
  140. return $signature;
  141. }
  142. public function rawurlencode($input) {
  143. if(is_array($input)) {
  144. return array_map(array(__CLASS__, 'rawurlencode'), $input);
  145. } elseif(is_scalar($input)) {
  146. return str_replace('%7E', '~', rawurlencode($input));
  147. } else {
  148. return '';
  149. }
  150. }
  151. private function _getImageBinary($files) {
  152. $keys = array_keys($files);
  153. $fileInfo = array();
  154. foreach($keys as $key) {
  155. if($key != 'remote') {
  156. $fileInfo[$key]['file'] = $files[$key];
  157. $imgInfo = getimagesize($files[$key]);
  158. $fileInfo[$key]['mime'] = $imgInfo['mime'];
  159. $contents = $use_include_path = null;
  160. if($files['remote']) {
  161. $opt = array(
  162. 'http' => array(
  163. 'timeout' => 10,
  164. )
  165. );
  166. $contents = stream_context_create($opt);
  167. }
  168. $files[$key] = file_get_contents($files[$key], $use_include_path, $contents);
  169. }
  170. }
  171. unset($files['remote']);
  172. return array('binary' => $files, 'fileInfo' => $fileInfo);
  173. }
  174. }