Connect.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  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: Connect.php 36278 2016-12-09 07:52:35Z nemohou $
  7. */
  8. if(!defined('IN_DISCUZ')) {
  9. exit('Access Denied');
  10. }
  11. class Cloud_Service_Connect {
  12. const SPECIAL_GID = 7;
  13. protected static $_instance;
  14. public $state = '';
  15. public static function getInstance() {
  16. if (!(self::$_instance instanceof self)) {
  17. self::$_instance = new self();
  18. }
  19. return self::$_instance;
  20. }
  21. public function __construct($siteId = '', $siteKey = '') {
  22. }
  23. public function connectMergeMember() {
  24. global $_G;
  25. static $merged;
  26. if($merged) {
  27. return;
  28. }
  29. $connect_member = C::t('#qqconnect#common_member_connect')->fetch($_G['uid']);
  30. if ($connect_member) {
  31. $_G['member'] = array_merge($_G['member'], $connect_member);
  32. $user_auth_fields = $connect_member['conisfeed'];
  33. if ($user_auth_fields == 0) {
  34. $_G['member']['is_user_info'] = 0;
  35. $_G['member']['is_feed'] = 0;
  36. } elseif ($user_auth_fields == 1) {
  37. $_G['member']['is_user_info'] = 1;
  38. $_G['member']['is_feed'] = 1;
  39. } elseif ($user_auth_fields == 2) {
  40. $_G['member']['is_user_info'] = 1;
  41. $_G['member']['is_feed'] = 0;
  42. } elseif ($user_auth_fields == 3) {
  43. $_G['member']['is_user_info'] = 0;
  44. $_G['member']['is_feed'] = 1;
  45. }
  46. unset($connect_member, $_G['member']['conisfeed']);
  47. }
  48. $merged = true;
  49. }
  50. public function connectUserBindParams() {
  51. global $_G;
  52. $this->connectMergeMember();
  53. getuserprofile('birthyear');
  54. getuserprofile('birthmonth');
  55. getuserprofile('birthday');
  56. switch ($_G['member']['gender']) {
  57. case 1 :
  58. $sex = 'male';
  59. break;
  60. case 2 :
  61. $sex = 'female';
  62. break;
  63. default :
  64. $sex = 'unknown';
  65. }
  66. $is_public_email = 2;
  67. $is_use_qq_avatar = $_G['member']['conisqzoneavatar'] == 1 ? 1 : 2;
  68. $birthday = sprintf('%04d', $_G['member']['birthyear']).'-'.sprintf('%02d', $_G['member']['birthmonth']).'-'.sprintf('%02d', $_G['member']['birthday']);
  69. $agent = md5(time().rand().uniqid());
  70. $inputArray = array (
  71. 'uid' => $_G['uid'],
  72. 'agent' => $agent,
  73. 'time' => TIMESTAMP
  74. );
  75. require_once DISCUZ_ROOT.'./config/config_ucenter.php';
  76. $input = 'uid='.$_G['uid'].'&agent='.$agent.'&time='.TIMESTAMP;
  77. $avatar_input = authcode($input, 'ENCODE', UC_KEY);
  78. $params = array (
  79. 'oauth_consumer_key' => $_G['setting']['connectappid'],
  80. 'u_id' => $_G['uid'],
  81. 'username' => $_G['member']['username'],
  82. 'email' => $_G['member']['email'],
  83. 'birthday' => $birthday,
  84. 'sex' => $sex,
  85. 'is_public_email' => $is_public_email,
  86. 'is_use_qq_avatar' => $is_use_qq_avatar,
  87. 's_id' => null,
  88. 'avatar_input' => $avatar_input,
  89. 'avatar_agent' => $agent,
  90. 'site_ucenter_id' => UC_APPID,
  91. 'source' => 'qzone',
  92. );
  93. return $params;
  94. }
  95. public function connectFeedResendJs() {
  96. global $_G;
  97. $jsname = $_G['cookie']['connect_js_name'];
  98. if($jsname != 'feed_resend') {
  99. return false;
  100. }
  101. $params = dunserialize(base64_decode($_G['cookie']['connect_js_params']));
  102. $params['sig'] = $this->connectGetSig($params, $this->connectGetSigKey());
  103. $jsurl = $_G['connect']['discuz_new_feed_url'];
  104. $utilService = Cloud::loadClass('Service_Util');
  105. $jsurl .= '?' . $utilService->httpBuildQuery($params, '', '&');
  106. return $jsurl;
  107. }
  108. public function connectCookieLoginJs() {
  109. global $_G;
  110. return $ajaxUrl = 'connect.php?mod=check&op=cookie';
  111. }
  112. public function connectGetSigKey() {
  113. global $_G;
  114. return $_G['setting']['connectappid'] . '|' . $_G['setting']['connectappkey'];
  115. }
  116. public function connectGetSig($params, $app_key) {
  117. ksort($params);
  118. $base_string = '';
  119. foreach($params as $key => $value) {
  120. $base_string .= $key.'='.$value;
  121. }
  122. $base_string .= $app_key;
  123. return md5($base_string);
  124. }
  125. public function connectParseBbcode($bbcode, $fId, $pId, $isHtml, &$attachImages) {
  126. include_once libfile('function/discuzcode');
  127. $result = preg_replace('/\[hide(=\d+)?\].+?\[\/hide\](\r\n|\s)/i', '', $bbcode);
  128. $result = preg_replace('/\[payto(=\d+)?\].+?\[\/payto\](\r\n|\s)/i', '', $result);
  129. $result = preg_replace('/\[quote\].*\[\/quote\](\r\n|\n|\r){0,}/is', '', $result);
  130. $result = discuzcode($result, 0, 0, $isHtml, 1, 2, 1, 0, 0, 0, 0, 1, 0);
  131. $result = strip_tags($result, '<img><a>');
  132. $result = preg_replace('/<img src="images\//i', "<img src=\"".$_G['siteurl']."images/", $result);
  133. $result = $this->connectParseAttach($result, $fId, $pId, $attachImages, $attachImageThumb);
  134. return $result;
  135. }
  136. public function connectParseAttach($content, $fId, $pId, &$attachImages) {
  137. global $_G;
  138. $permissions = $this->connectGetUserGroupPermissions(self::SPECIAL_GID, $fId);
  139. $visitorPermission = $permissions[self::SPECIAL_GID];
  140. $attachIds = array();
  141. $attachImages = array ();
  142. $attachments = C::t('forum_attachment')->fetch_all_by_id('pid', $pId);
  143. $attachments = C::t('forum_attachment_n')->fetch_all("pid:$pId", array_keys($attachments));
  144. foreach ($attachments as $k => $attach) {
  145. $aid = $attach['aid'];
  146. if($attach['isimage'] == 0 || $attach['price'] > 0 || $attach['readperm'] > $visitorPermission['readPermission'] || in_array($fId, $visitorPermission['forbidViewAttachForumIds']) || in_array($attach['aid'], $attachIds)) {
  147. continue;
  148. }
  149. $imageItem = array ();
  150. $thumbWidth = '100';
  151. $thumbHeight = '100';
  152. $bigWidth = '400';
  153. $bigHeight = '400';
  154. $thumbImageURL = $_G['siteurl'] . getforumimg($aid, 1, $thumbWidth, $thumbHeight, 'fixwr');
  155. $bigImageURL = $_G['siteurl'] . getforumimg($aid, 1, $bigWidth, $bigHeight, 'fixnone');
  156. $imageItem['aid'] = $aid;
  157. $imageItem['thumb'] = $thumbImageURL;
  158. $imageItem['big'] = $bigImageURL;
  159. if($attach['remote']) {
  160. $imageItem['path'] = $_G['setting']['ftp']['attachurl'].'forum/'.$attach['attachment'];
  161. $imageItem['remote'] = true;
  162. } else {
  163. $imageItem['path'] = $_G['setting']['attachdir'].'forum/'.$attach['attachment'];
  164. }
  165. $attachIds[] = $aid;
  166. $attachImages[] = $imageItem;
  167. }
  168. $this->connectParseAttach_callback_connectParseAttachTag_1($attachNames, 1);
  169. $content = preg_replace_callback('/\[attach\](\d+)\[\/attach\]/i', array($this, 'connectParseAttach_callback_connectParseAttachTag_1'), $content);
  170. return $content;
  171. }
  172. public function connectParseAttach_callback_connectParseAttachTag_1($matches, $action = 0) {
  173. static $attachNames = '';
  174. if($action == 1) {
  175. $attachNames = $matches;
  176. } else {
  177. return $this->connectParseAttachTag($matches[1], $attachNames);
  178. }
  179. }
  180. public function connectParseAttachTag($attachId, $attachNames) {
  181. include_once libfile('function/discuzcode');
  182. if(array_key_exists($attachId, $attachNames)) {
  183. return '<span class="attach"><a href="'.$_G['siteurl'].'/attachment.php?aid='.aidencode($attachId).'">'.$attachNames[$attachId].'</a></span>';
  184. }
  185. return '';
  186. }
  187. function connectGetUserGroupPermissions($gid, $fid) {
  188. global $_G;
  189. loadcache('usergroups');
  190. $fields = array (
  191. 'groupid' => 'userGroupId',
  192. 'grouptitle' => 'userGroupName',
  193. 'readaccess' => 'readPermission',
  194. 'allowvisit' => 'allowVisit'
  195. );
  196. $userGroup = C::t('common_usergroup')->fetch_all($gid);
  197. $userGroupInfo = array();
  198. foreach ($userGroup as $id => $value) {
  199. $userGroupInfo[$id] = array_merge($value, $_G['cache']['usergroups'][$id]);
  200. $userGroupInfo[$id]['forbidForumIds'] = array ();
  201. $userGroupInfo[$id]['allowForumIds'] = array ();
  202. $userGroupInfo[$id]['specifyAllowForumIds'] = array ();
  203. $userGroupInfo[$id]['allowViewAttachForumIds'] = array ();
  204. $userGroupInfo[$id]['forbidViewAttachForumIds'] = array ();
  205. foreach ($fields as $k => $v) {
  206. $userGroupInfo[$id][$v] = $userGroupInfo[$id][$k];
  207. }
  208. }
  209. $forumField = C::t('forum_forumfield')->fetch($fid);
  210. $allowViewGroupIds = array ();
  211. if($forumField['viewperm']) {
  212. $allowViewGroupIds = explode("\t", $forumField['viewperm']);
  213. }
  214. $allowViewAttachGroupIds = array ();
  215. if($forumField['getattachperm']) {
  216. $allowViewAttachGroupIds = explode("\t", $forumField['getattachperm']);
  217. }
  218. foreach ($userGroupInfo as $groupId => $value) {
  219. if($forumField['password']) {
  220. $userGroupInfo[$groupId]['forbidForumIds'][] = $fid;
  221. continue;
  222. }
  223. $perm = unserialize($forumField['formulaperm']);
  224. if(is_array($perm)) {
  225. if($perm[0] || $perm[1] || $perm['users']) {
  226. $userGroupInfo[$groupId]['forbidForumIds'][] = $fid;
  227. continue;
  228. }
  229. }
  230. if(!$allowViewGroupIds) {
  231. $userGroupInfo[$groupId]['allowForumIds'][] = $fid;
  232. } elseif (!in_array($groupId, $allowViewGroupIds)) {
  233. $userGroupInfo[$groupId]['forbidForumIds'][] = $fid;
  234. } elseif (in_array($groupId, $allowViewGroupIds)) {
  235. $userGroupInfo[$groupId]['allowForumIds'][] = $fid;
  236. $userGroupInfo[$groupId]['specifyAllowForumIds'][] = $fid;
  237. }
  238. if(!$allowViewAttachGroupIds) {
  239. $userGroupInfo[$groupId]['allowViewAttachForumIds'][] = $fid;
  240. } elseif (!in_array($groupId, $allowViewAttachGroupIds)) {
  241. $userGroupInfo[$groupId]['forbidViewAttachForumIds'][] = $fid;
  242. } elseif (in_array($groupId, $allowViewGroupIds)) {
  243. $userGroupInfo[$groupId]['allowViewAttachForumIds'][] = $fid;
  244. }
  245. }
  246. return $userGroupInfo;
  247. }
  248. public function connectOutputPhp($url, $postData = '') {
  249. global $_G;
  250. $response = dfsockopen($url, 0, $postData, '', false, $_G['setting']['cloud_api_ip']);
  251. $result = (array) dunserialize($response);
  252. return $result;
  253. }
  254. public function connectJsOutputMessage($msg = '', $errMsg = '', $errCode = '') {
  255. $result = array (
  256. 'result' => $msg,
  257. 'errMessage' => $errMsg,
  258. 'errCode' => $errCode
  259. );
  260. echo sprintf('con_handle_response(%s);', json_encode($this->_connectUrlencode($result)));
  261. exit;
  262. }
  263. protected function _connectUrlencode($value) {
  264. if (is_array($value)) {
  265. foreach ($value as $k => $v) {
  266. $value[$k] = $this->_connectUrlencode($v);
  267. }
  268. } else if (is_string($value)) {
  269. $value = urlencode(str_replace(array("\r\n", "\r", "\n", "\"", "\/", "\t"), array('\\n', '\\n', '\\n', '\\"', '\\/', '\\t'), $value));
  270. }
  271. return $value;
  272. }
  273. public function connectCookieLoginParams() {
  274. global $_G;
  275. $this->connectMergeMember();
  276. $oauthToken = $_G['member']['conuin'];
  277. $api_url = $_G['connect']['api_url'].'/connect/discuz/cookieReport';
  278. if($oauthToken) {
  279. $extra = array (
  280. 'oauth_token' => $oauthToken
  281. );
  282. $sig_params = $this->connectGetOauthSignatureParams($extra);
  283. $oauth_token_secret = $_G['member']['conuinsecret'];
  284. $sig_params['oauth_signature'] = $this->connectGetOauthSignature($api_url, $sig_params, 'POST', $oauth_token_secret);
  285. $params = array (
  286. 'client_ip' => $_G['clientip'],
  287. 'u_id' => $_G['uid'],
  288. 'version' => 'qzone1.0',
  289. );
  290. $params = array_merge($sig_params, $params);
  291. $params['response_type'] = 'php';
  292. return $params;
  293. } else {
  294. return false;
  295. }
  296. }
  297. function connectAddCookieLogins() {
  298. global $_G;
  299. loadcache('connect_has_setting_count');
  300. if (!$_G['cache']['connect_has_setting_count']) {
  301. $times = C::t('common_setting')->fetch('connect_login_times');
  302. C::t('common_setting')->update('connect_login_times', $times + 1);
  303. savecache('connect_has_setting_count', '1');
  304. } else {
  305. C::t('common_setting')->update_count('connect_login_times', 1);
  306. }
  307. $life = 86400;
  308. $current_date = date('Y-m-d');
  309. dsetcookie('connect_last_report_time', $current_date, $life);
  310. return true;
  311. }
  312. public function connectAjaxOuputMessage($msg = '', $errCode = '') {
  313. @header("Content-type: text/html; charset=".CHARSET);
  314. echo "errCode=$errCode&result=$msg";
  315. exit;
  316. }
  317. public function connectGetOauthSignature($url, $params, $method = 'POST', $oauth_token_secret = '') {
  318. global $_G;
  319. $method = strtoupper($method);
  320. if(!in_array($method, array ('GET', 'POST'))) {
  321. return FALSE;
  322. }
  323. $url = urlencode($url);
  324. $utilService = Cloud::loadClass('Service_Util');
  325. $param_str = urlencode($utilService->httpBuildQuery($params, '', '&'));
  326. $base_string = $method.'&'.$url.'&'.$param_str;
  327. $key = $_G['setting']['connectappkey'].'&'.$oauth_token_secret;
  328. $signature = $utilService->hashHmac('sha1', $base_string, $key);
  329. return $signature;
  330. }
  331. public function connectGetOauthSignatureParams($extra = array ()) {
  332. global $_G;
  333. $params = array (
  334. 'oauth_consumer_key' => $_G['setting']['connectappid'],
  335. 'oauth_nonce' => $this->_connectGetNonce(),
  336. 'oauth_signature_method' => 'HMAC_SHA1',
  337. 'oauth_timestamp' => TIMESTAMP
  338. );
  339. if($extra) {
  340. $params = array_merge($params, $extra);
  341. }
  342. ksort($params);
  343. return $params;
  344. }
  345. protected function _connectGetNonce() {
  346. $mt = microtime();
  347. $rand = mt_rand();
  348. return md5($mt.$rand);
  349. }
  350. public function connectParseXml($contents, $getAttributes = true, $priority = 'tag') {
  351. if (!$contents) {
  352. return array();
  353. }
  354. if (!function_exists('xml_parser_create')) {
  355. return array();
  356. }
  357. $parser = xml_parser_create('');
  358. xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
  359. xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
  360. xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
  361. xml_parse_into_struct($parser, trim($contents), $xmlValues);
  362. xml_parser_free($parser);
  363. if (!$xmlValues) {
  364. return;
  365. }
  366. $xmlArray = $parent = array();
  367. $current = &$xmlArray;
  368. $repeatedTagIndex = array();
  369. foreach($xmlValues as $data) {
  370. unset($attributes, $value);
  371. extract($data);
  372. $result = $attributesData = array();
  373. if (isset($value)) {
  374. if ($priority == 'tag') {
  375. $result = $value;
  376. } else {
  377. $result['value'] = $value;
  378. }
  379. }
  380. if (isset($attributes) && $getAttributes) {
  381. foreach ($attributes as $attr => $val) {
  382. if ($priority == 'tag') {
  383. $attributesData[$attr] = $val;
  384. } else {
  385. $result['attr'][$attr] = $val;
  386. }
  387. }
  388. }
  389. if ($type == 'open') {
  390. $parent[$level - 1] = &$current;
  391. if (!is_array($current) || (!in_array($tag, array_keys($current)))) {
  392. $current[$tag] = $result;
  393. if ($attributesData) {
  394. $current[$tag . '_attr'] = $attributesData;
  395. }
  396. $repeatedTagIndex[$tag . '_' . $level] = 1;
  397. $current = &$current[$tag];
  398. } else {
  399. if (isset($current[$tag][0])) {
  400. $current[$tag][$repeatedTagIndex[$tag . '_' . $level]] = $result;
  401. $repeatedTagIndex[$tag . '_' . $level] ++;
  402. } else {
  403. $current[$tag] = array($current[$tag], $result);
  404. $repeatedTagIndex[$tag . '_' . $level] = 2;
  405. if (isset($current[$tag . '_attr'])) {
  406. $current[$tag]['0_attr'] = $current[$tag . '_attr'];
  407. unset($current[$tag . '_attr']);
  408. }
  409. }
  410. $lastItemIndex = $repeatedTagIndex[$tag . '_' . $level] - 1;
  411. $current = &$current[$tag][$lastItemIndex];
  412. }
  413. } elseif($type == 'complete') {
  414. if (!isset($current[$tag])) {
  415. $current[$tag] = $result;
  416. $repeatedTagIndex[$tag . '_' . $level] = 1;
  417. if ($priority == 'tag' && $attributesData) {
  418. $current[$tag . '_attr'] = $attributesData;
  419. }
  420. } else {
  421. if (isset($current[$tag][0]) && is_array($current[$tag])) {
  422. $current[$tag][$repeatedTagIndex[$tag . '_' . $level]] = $result;
  423. if ($priority == 'tag' && $getAttributes && $attributesData) {
  424. $current[$tag][$repeatedTagIndex[$tag . '_' . $level] . '_attr'] = $attributesData;
  425. }
  426. $repeatedTagIndex[$tag . '_' . $level] ++;
  427. } else {
  428. $current[$tag] = array($current[$tag], $result);
  429. $repeatedTagIndex[$tag . '_' . $level] = 1;
  430. if ($priority == 'tag' && $getAttributes) {
  431. if (isset($current[$tag . '_attr'])) {
  432. $current[$tag]['0_attr'] = $current[$tag . '_attr'];
  433. unset($current[$tag . '_attr']);
  434. }
  435. if ($attributesData) {
  436. $current[$tag][$repeatedTagIndex[$tag . '_' . $level] . '_attr'] = $attributesData;
  437. }
  438. }
  439. $repeatedTagIndex[$tag . '_' . $level] ++;
  440. }
  441. }
  442. } elseif($type == 'close') {
  443. $current = &$parent[$level - 1];
  444. }
  445. }
  446. return $xmlArray[key($parent[0])] ? $xmlArray[key($parent[0])] : $xmlArray;
  447. }
  448. public function connectFilterUsername($username) {
  449. $username = str_replace(' ', '_', trim($username));
  450. return cutstr($username, 15, '');
  451. }
  452. public function connectErrlog($errno, $error) {
  453. return true;
  454. }
  455. function connectCookieLoginReport($loginTimes) {
  456. global $_G;
  457. $utilService = Cloud::loadClass('Service_Util');
  458. $response = '';
  459. if ($loginTimes) {
  460. $api_url = $_G['connect']['api_url'].'/connect/discuz/batchCookieReport';
  461. $params = array (
  462. 'oauth_consumer_key' => $_G['setting']['connectappid'],
  463. 'login_times' => $loginTimes,
  464. 'date' => dgmdate(TIMESTAMP - 86400, 'Y-m-d'),
  465. 'ts' => TIMESTAMP,
  466. );
  467. $params['sig'] = $this->connectGetSig($params, $this->connectGetSigKey());
  468. $response = $this->connectOutputPhp($api_url.'?', $utilService->httpBuildQuery($params, '', '&'));
  469. } else {
  470. $response = array('status' => 0);
  471. }
  472. return $response;
  473. }
  474. }