|
@@ -0,0 +1,575 @@
|
|
|
|
|
+<?php
|
|
|
|
|
+
|
|
|
|
|
+define('ROOT_PATH', dirname(__FILE__).'/../../');
|
|
|
|
|
+
|
|
|
|
|
+class _dzRestful {
|
|
|
|
|
+
|
|
|
|
|
+ private $apiParam;
|
|
|
|
|
+
|
|
|
|
|
+ private $postParam;
|
|
|
|
|
+
|
|
|
|
|
+ public $token;
|
|
|
|
|
+
|
|
|
|
|
+ public $tokenData;
|
|
|
|
|
+
|
|
|
|
|
+ private $_appId;
|
|
|
|
|
+
|
|
|
|
|
+ private $_m;
|
|
|
|
|
+
|
|
|
|
|
+ const SignTTL = 300;
|
|
|
|
|
+
|
|
|
|
|
+ const TokenTTL = 3600;
|
|
|
|
|
+
|
|
|
|
|
+ const TokenSaveTTL = 86400 * 30;
|
|
|
|
|
+
|
|
|
|
|
+ const AuthTokenTTL = 300;
|
|
|
|
|
+
|
|
|
|
|
+ const TokenPre = 'rToken_';
|
|
|
|
|
+
|
|
|
|
|
+ const AuthTokenPre = 'rAuthToken_';
|
|
|
|
|
+
|
|
|
|
|
+ const AppIdConfPre = 'rApp_';
|
|
|
|
|
+
|
|
|
|
|
+ const ApiConfPre = 'rApi_';
|
|
|
|
|
+ const ApiFreqPre = 'rFreq_';
|
|
|
|
|
+ const ApiFreqTTL = 60;
|
|
|
|
|
+
|
|
|
|
|
+ const AuthPre = 'rAuth_';
|
|
|
|
|
+ const AuthTTL = 60;
|
|
|
|
|
+
|
|
|
|
|
+ const Error = [
|
|
|
|
|
+ -100 => 'run: script is exception',
|
|
|
|
|
+ -101 => 'checkSign: param is missing',
|
|
|
|
|
+ -102 => 'checkSign: appid is invalid',
|
|
|
|
|
+ -103 => 'checkSign: sign is expire',
|
|
|
|
|
+ -104 => 'checkSign: sign is invalid',
|
|
|
|
|
+ -105 => 'checkToken: token is missing',
|
|
|
|
|
+ -106 => 'checkToken: token is expire',
|
|
|
|
|
+ -107 => 'checkToken: appid is error',
|
|
|
|
|
+ -108 => 'getTokenData: token is error',
|
|
|
|
|
+ -109 => 'getApiParam: api is invalid',
|
|
|
|
|
+ -110 => 'getAppidPerm: appid is invalid',
|
|
|
|
|
+ -111 => 'getSecret: appid is invalid',
|
|
|
|
|
+ -112 => 'parseQuery: api url is empty',
|
|
|
|
|
+ -113 => 'parseQuery: api url is error',
|
|
|
|
|
+ -114 => 'initParam: api is invalid',
|
|
|
|
|
+ -115 => 'apiPermCheck: api is invalid',
|
|
|
|
|
+ -116 => 'apiFreqCheck: out of frequency',
|
|
|
|
|
+ -117 => 'scriptCheck: script is empty',
|
|
|
|
|
+ -118 => 'scriptCheck: script format is error',
|
|
|
|
|
+ -119 => 'callback: authtoken is invalid',
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ const Developer = false;
|
|
|
|
|
+
|
|
|
|
|
+ public function __construct($postParam = []) {
|
|
|
|
|
+ require_once ROOT_PATH.'./source/function/function_core.php';
|
|
|
|
|
+ $this->postParam = $postParam;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function parseQuery() {
|
|
|
|
|
+ $s = rawurldecode($_SERVER['QUERY_STRING']);
|
|
|
|
|
+ if(!$s) {
|
|
|
|
|
+ $this->error(-112);
|
|
|
|
|
+ }
|
|
|
|
|
+ if(str_ends_with($s, '=')) {
|
|
|
|
|
+ $s = substr($s, 0, -1);
|
|
|
|
|
+ }
|
|
|
|
|
+ if(!str_starts_with($s, '/')) {
|
|
|
|
|
+ $s = '/'.$s;
|
|
|
|
|
+ }
|
|
|
|
|
+ $e = explode('/', $s);
|
|
|
|
|
+ $c = count($e);
|
|
|
|
|
+ if(preg_match('/^v\d+$/', $e[$c - 1])) {
|
|
|
|
|
+ $api = array_slice($e, 1, -1);
|
|
|
|
|
+ $ver = $e[$c - 1];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $api = array_slice($e, 1);
|
|
|
|
|
+ $ver = 'v1';
|
|
|
|
|
+ }
|
|
|
|
|
+ if(!$api || !$ver) {
|
|
|
|
|
+ $this->error(-113);
|
|
|
|
|
+ }
|
|
|
|
|
+ return [$api, $ver];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function initParam($api, $ver) {
|
|
|
|
|
+ $apiParams = $this->_getApiParam($api, $ver);
|
|
|
|
|
+ $key = '/'.implode('/', $api);
|
|
|
|
|
+ if(empty($apiParams[$key])) {
|
|
|
|
|
+ $this->error(-114);
|
|
|
|
|
+ }
|
|
|
|
|
+ $params = $apiParams[$key];
|
|
|
|
|
+ $params['perms'] = [$key.'/'.$ver];
|
|
|
|
|
+ $this->apiParam = $params;
|
|
|
|
|
+ return $params['script'];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function paramDecode($key) {
|
|
|
|
|
+ if(empty($this->apiParam[$key])) {
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(is_array($this->apiParam[$key])) {
|
|
|
|
|
+ $v = $this->apiParam[$key];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $_tmp = unserialize($this->apiParam[$key]);
|
|
|
|
|
+ $v = $_tmp === false ? $this->apiParam[$key] : $_tmp;
|
|
|
|
|
+ }
|
|
|
|
|
+ return $this->_replacePostParams($v);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function getRequestParam() {
|
|
|
|
|
+ return !empty($this->postParam['_REQUEST']) ? json_decode($this->postParam['_REQUEST'], true) : [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function getShutdownFunc() {
|
|
|
|
|
+ $output = !empty($this->apiParam['output']) ? $this->apiParam['output'] : [];
|
|
|
|
|
+ $rawOutput = !empty($this->apiParam['raw']);
|
|
|
|
|
+ $shutdownFunc = 'showOutput';
|
|
|
|
|
+ if($rawOutput) {
|
|
|
|
|
+ $shutdownFunc = 'rawOutput';
|
|
|
|
|
+ } elseif($output) {
|
|
|
|
|
+ $shutdownFunc = 'convertOutput';
|
|
|
|
|
+ }
|
|
|
|
|
+ return [$shutdownFunc, $output];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function _replacePostParams($v) {
|
|
|
|
|
+ foreach($v as $_k => $_v) {
|
|
|
|
|
+ if(is_array($_v)) {
|
|
|
|
|
+ $v[$_k] = $this->_replacePostParams($_v);
|
|
|
|
|
+ } elseif(is_string($_v)) {
|
|
|
|
|
+ if(str_starts_with($_v, '{') && preg_match('/^\{:(\w+):\}$/', $_v, $r)) {
|
|
|
|
|
+ $v[$_k] = !empty($this->postParam[$r[1]]) ? $this->postParam[$r[1]] : null;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return $v;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function apiPermCheck() {
|
|
|
|
|
+ if(!empty($this->tokenData['_conf']['apis']) && !array_intersect($this->apiParam['perms'], $this->tokenData['_conf']['apis'])) {
|
|
|
|
|
+ $this->error(-115);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function apiFreqCheck() {
|
|
|
|
|
+ $api = $this->apiParam['perms'][0];
|
|
|
|
|
+ if(!empty($this->tokenData['_conf']['freq'][$api])) {
|
|
|
|
|
+ $key = self::ApiFreqPre.$this->_appId.'_'.$api;
|
|
|
|
|
+ $v = $this->_memory('get', [$key]);
|
|
|
|
|
+ if(!$v) {
|
|
|
|
|
+ $this->_memory('inc', [$key]);
|
|
|
|
|
+ $this->_memory('expire', [$key, 10]);//self::ApiFreqTTL
|
|
|
|
|
+ } elseif($v >= $this->tokenData['_conf']['freq'][$api]) {
|
|
|
|
|
+ $this->error(-116);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $this->_memory('inc', [$key]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function scriptCheck() {
|
|
|
|
|
+ if(empty($this->apiParam['script'])) {
|
|
|
|
|
+ $this->error(-117);
|
|
|
|
|
+ }
|
|
|
|
|
+ if(!preg_match('/^\w+$/', $this->apiParam['script'])) {
|
|
|
|
|
+ $this->error(-118);
|
|
|
|
|
+ }
|
|
|
|
|
+ return $this->apiParam['script'];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function error($code) {
|
|
|
|
|
+ $this->output([
|
|
|
|
|
+ 'ret' => $code,
|
|
|
|
|
+ 'msg' => !empty(self::Error[$code]) ? self::Error[$code] : '',
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function output($value) {
|
|
|
|
|
+ $this->_setSysVar($return['data'], $value);
|
|
|
|
|
+ echo json_encode($value);
|
|
|
|
|
+ exit;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function showOutput() {
|
|
|
|
|
+ $return = ['ret' => 0];
|
|
|
|
|
+
|
|
|
|
|
+ $s = ob_get_contents();
|
|
|
|
|
+ ob_end_clean();
|
|
|
|
|
+ $return['data']['content'] = $s;
|
|
|
|
|
+
|
|
|
|
|
+ $this->plugin('after', $return['data']);
|
|
|
|
|
+ $this->output($return);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function rawOutput() {
|
|
|
|
|
+ $newTokenData = $this->updateTokenData();
|
|
|
|
|
+ if($newTokenData) {
|
|
|
|
|
+ $ttl = $this->tokenData['refreshExptime'] - time();
|
|
|
|
|
+ $this->setToken($this->token, $newTokenData, $ttl);
|
|
|
|
|
+ }
|
|
|
|
|
+ exit;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function convertOutput($output) {
|
|
|
|
|
+ ob_end_clean();
|
|
|
|
|
+ $return = ['ret' => 0];
|
|
|
|
|
+
|
|
|
|
|
+ $tmp = $GLOBALS;
|
|
|
|
|
+ foreach($output as $k => $v) {
|
|
|
|
|
+ if(str_contains($k, '/')) {
|
|
|
|
|
+ $return['data'][$v] = $this->_arrayVar($tmp, $k);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $return['data'][$v] = $this->_singleVar($tmp, $k);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ $this->plugin('after', $return['data']);
|
|
|
|
|
+
|
|
|
|
|
+ $this->output($return);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function plugin($type, &$data) {
|
|
|
|
|
+ if(empty($this->apiParam['plugin'][$type])) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ foreach($this->apiParam['plugin'][$type] as $method => $value) {
|
|
|
|
|
+ $vars = explode(':', $method);
|
|
|
|
|
+ if(count($vars) == 2) {
|
|
|
|
|
+ if(!preg_match('/^\w+$/', $vars[0])) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ require_once ROOT_PATH.'./source/function/function_path.php';
|
|
|
|
|
+ $f = ROOT_PATH.PLUGIN_ROOT.$vars[0].'/restful.class.php';
|
|
|
|
|
+ $c = 'restful_'.$vars[0];
|
|
|
|
|
+ $m = $vars[1];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $f = ROOT_PATH.'./source/class/class_restfulplugin.php';
|
|
|
|
|
+ $c = 'restfulplugin';
|
|
|
|
|
+ $m = $method;
|
|
|
|
|
+ }
|
|
|
|
|
+ if(!file_exists($f)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ @require_once $f;
|
|
|
|
|
+ if(!class_exists($c) || !method_exists($c, $m)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ call_user_func_array([$c, $m], [&$data, explode(',', $value['param'] ?? '')]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function sessionDecode() {
|
|
|
|
|
+ $session = unserialize(base64_decode($this->tokenData['_session']));
|
|
|
|
|
+ if(!empty($this->postParam['_authSign'])) {
|
|
|
|
|
+ $this->decodeAuthSign($session);
|
|
|
|
|
+ }
|
|
|
|
|
+ return $session;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function checkSign() {
|
|
|
|
|
+ if(empty($_SERVER['HTTP_APPID']) ||
|
|
|
|
|
+ empty($_SERVER['HTTP_SIGN']) ||
|
|
|
|
|
+ empty($_SERVER['HTTP_NONCE']) ||
|
|
|
|
|
+ empty($_SERVER['HTTP_T'])) {
|
|
|
|
|
+ $this->error(-101);
|
|
|
|
|
+ }
|
|
|
|
|
+ $this->_getAppidPerm($_SERVER['HTTP_APPID']);
|
|
|
|
|
+ $secret = $this->_getSecret();
|
|
|
|
|
+ if(!$secret) {
|
|
|
|
|
+ $this->error(-102);
|
|
|
|
|
+ }
|
|
|
|
|
+ if(time() - $_SERVER['HTTP_T'] > self::SignTTL) {
|
|
|
|
|
+ $this->error(-103);
|
|
|
|
|
+ }
|
|
|
|
|
+ if($_SERVER['HTTP_SIGN'] != base64_encode(hash('sha256', $_SERVER['HTTP_NONCE'].$_SERVER['HTTP_T'].$secret))) {
|
|
|
|
|
+ $this->error(-104);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function checkToken() {
|
|
|
|
|
+ if(empty($this->_getToken())) {
|
|
|
|
|
+ $this->error(-105);
|
|
|
|
|
+ }
|
|
|
|
|
+ $v = $this->_getTokenData();
|
|
|
|
|
+ if(time() >= $v['exptime']) {
|
|
|
|
|
+ $this->error(-106);
|
|
|
|
|
+ }
|
|
|
|
|
+ $this->tokenData = $v;
|
|
|
|
|
+ if(!$v['_appid'] || $v['_appid'] != $_SERVER['HTTP_APPID']) {
|
|
|
|
|
+ $this->error(-107);
|
|
|
|
|
+ }
|
|
|
|
|
+ $this->_getAppidPerm($v['_appid']);
|
|
|
|
|
+ $this->postParam['formhash'] = !empty($this->tokenData['_formhash']) ? $this->tokenData['_formhash'] : '';
|
|
|
|
|
+ $this->token = $this->_getToken();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function setToken($key, $value, $ttl = self::TokenSaveTTL) {
|
|
|
|
|
+ $this->_memory('set', [self::TokenPre.$key, serialize($value), $ttl]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function setAuthToken($token, $value) {
|
|
|
|
|
+ if($this->getAuthToken($token)) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ global $_G;
|
|
|
|
|
+ $value = authcode(serialize($value), 'ENCODE', md5($_G['config']['security']['authkey']));
|
|
|
|
|
+ $this->_memory('set', [self::AuthTokenPre.$token, $value, self::AuthTokenTTL]);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function getAuthToken($token) {
|
|
|
|
|
+ global $_G;
|
|
|
|
|
+ $value = $this->_memory('get', [self::AuthTokenPre.$token]);
|
|
|
|
|
+ return $value ? dunserialize(authcode($value, 'DECODE', md5($_G['config']['security']['authkey']))) : [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function isRefreshToken() {
|
|
|
|
|
+ return !empty($this->_getToken());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function _getToken() {
|
|
|
|
|
+ return !empty($_SERVER['HTTP_TOKEN']) ? $_SERVER['HTTP_TOKEN'] : (!empty($this->postParam['token']) ? $this->postParam['token'] : '');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function _getTokenData() {
|
|
|
|
|
+ $v = dunserialize($this->_memory('get', [self::TokenPre.$this->_getToken()]));
|
|
|
|
|
+ if(empty($v)) {
|
|
|
|
|
+ $this->error(-108);
|
|
|
|
|
+ }
|
|
|
|
|
+ return $v;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function refreshTokenData() {
|
|
|
|
|
+ $v = $this->_getTokenData();
|
|
|
|
|
+ $data['_session'] = $v['_session'];
|
|
|
|
|
+ $data['_formhash'] = $this->_singleVar($_G, 'formhash');
|
|
|
|
|
+ $data['_appid'] = $_SERVER['HTTP_APPID'];
|
|
|
|
|
+ $data['_conf'] = $this->tokenData['_conf'];
|
|
|
|
|
+ $data['exptime'] = time() + self::TokenTTL;
|
|
|
|
|
+ $data['refreshExptime'] = time() + self::TokenSaveTTL;
|
|
|
|
|
+ return serialize($data);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function delTokenData() {
|
|
|
|
|
+ $this->_memory('rm', [self::TokenPre.$this->_getToken()]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function newTokenData() {
|
|
|
|
|
+ global $_G;
|
|
|
|
|
+ $data = [];
|
|
|
|
|
+ $data['_session'] = $this->_sessionEncode($_COOKIE);
|
|
|
|
|
+ $data['_formhash'] = $this->_singleVar($_G, 'formhash');
|
|
|
|
|
+ $data['_appid'] = $_SERVER['HTTP_APPID'];
|
|
|
|
|
+ $data['_conf'] = $this->tokenData['_conf'];
|
|
|
|
|
+ $data['exptime'] = time() + self::TokenTTL;
|
|
|
|
|
+ $data['refreshExptime'] = time() + self::TokenSaveTTL;
|
|
|
|
|
+ return serialize($data);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function _getApiParam($api, $ver) {
|
|
|
|
|
+ if(self::Developer) {
|
|
|
|
|
+ return $this->_getApiParam_Developer($api, $ver);
|
|
|
|
|
+ }
|
|
|
|
|
+ $v = $this->_memory('get', [self::ApiConfPre.'/'.$api[0].'_'.$ver]);
|
|
|
|
|
+ if(!$v) {
|
|
|
|
|
+ $this->error(-109);
|
|
|
|
|
+ }
|
|
|
|
|
+ return $this->apiParam = dunserialize($v);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function _getAppidPerm($appid) {
|
|
|
|
|
+ $v = $this->_memory('get', [self::AppIdConfPre.$appid]);
|
|
|
|
|
+ if(!$v) {
|
|
|
|
|
+ if(!empty($GLOBALS['discuz'])) {
|
|
|
|
|
+ require_once libfile('function/cache');
|
|
|
|
|
+ updatecache('restful');
|
|
|
|
|
+ $v = $this->_memory('get', [self::AppIdConfPre.$appid]);
|
|
|
|
|
+ if(!$v) {
|
|
|
|
|
+ $this->error(-110);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $this->error(-110);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ $this->_appId = $appid;
|
|
|
|
|
+ $v = dunserialize($v);
|
|
|
|
|
+ $this->tokenData['_conf'] = $v;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function updateTokenData() {
|
|
|
|
|
+ global $_G;
|
|
|
|
|
+ $data = $this->tokenData;
|
|
|
|
|
+ $_session = $this->_sessionEncode($_COOKIE);
|
|
|
|
|
+ if(!empty($this->tokenData['_session']) && $_session == $this->tokenData['_session']) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ $data['_session'] = $_session;
|
|
|
|
|
+ $data['_formhash'] = $this->_singleVar($_G, 'formhash');
|
|
|
|
|
+ return serialize($data);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function _getSecret() {
|
|
|
|
|
+ if(empty($this->tokenData['_conf']['secret'])) {
|
|
|
|
|
+ $this->error(-111);
|
|
|
|
|
+ }
|
|
|
|
|
+ return $this->tokenData['_conf']['secret'];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function _sessionEncode($v) {
|
|
|
|
|
+ return base64_encode(serialize($v));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function _setSysVar(&$data, &$output = []) {
|
|
|
|
|
+ global $_G;
|
|
|
|
|
+
|
|
|
|
|
+ $newTokenData = $this->updateTokenData();
|
|
|
|
|
+ if(!empty($this->tokenData['refreshExptime']) && $newTokenData) {
|
|
|
|
|
+ $ttl = $this->tokenData['refreshExptime'] - time();
|
|
|
|
|
+ $this->setToken($this->token, $newTokenData, $ttl);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(!empty($_G['_multi'])) {
|
|
|
|
|
+ $output['multi'] = $_G['_multi'];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ unset($_G['config'],
|
|
|
|
|
+ $_G['setting']['siteuniqueid'],
|
|
|
|
|
+ $_G['setting']['ec_tenpay_opentrans_chnid'],
|
|
|
|
|
+ $_G['setting']['ec_tenpay_opentrans_key'],
|
|
|
|
|
+ $_G['setting']['ec_tenpay_bargainor'],
|
|
|
|
|
+ $_G['setting']['ec_tenpay_key'],
|
|
|
|
|
+ $_G['setting']['ec_account'],
|
|
|
|
|
+ $_G['setting']['ec_contract']);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function _singleVar(&$var, $k) {
|
|
|
|
|
+ return $var[$k] ?? null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function _arrayVar(&$var, $k) {
|
|
|
|
|
+ unset($GLOBALS['_L']['_G']);
|
|
|
|
|
+ $value = null;
|
|
|
|
|
+ $sVar = &$var;
|
|
|
|
|
+ $e = explode('/', $k);
|
|
|
|
|
+ $count = count($e);
|
|
|
|
|
+ foreach($e as $i => $_k) {
|
|
|
|
|
+ if($_k == '*') {
|
|
|
|
|
+ foreach($sVar as $_k3 => $_v3) {
|
|
|
|
|
+ $nKey = implode('/', array_slice($e, $i + 1));
|
|
|
|
|
+ $value[$_k3] = $this->_arrayVar($_v3, $nKey);
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ $isMulti = str_contains($_k, ',');
|
|
|
|
|
+ if(!isset($sVar[$_k]) && !$isMulti) {
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ if($isMulti) {
|
|
|
|
|
+ $value = null;
|
|
|
|
|
+ foreach(explode(',', $_k) as $_k2) {
|
|
|
|
|
+ $value[$_k2] = $this->_singleVar($sVar, $_k2);
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if($count - 1 == $i) {
|
|
|
|
|
+ $value = $this->_singleVar($sVar, $_k);
|
|
|
|
|
+ }
|
|
|
|
|
+ $sVar = &$sVar[$_k];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return $value;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function _memory($method, $params = []) {
|
|
|
|
|
+ if($this->_m == null) {
|
|
|
|
|
+ require_once ROOT_PATH.'./source/class/memory/memory_driver_redis.php';
|
|
|
|
|
+ $_config = [];
|
|
|
|
|
+ require ROOT_PATH.'./config/config_global.php';
|
|
|
|
|
+ $this->_m = new memory_driver_redis();
|
|
|
|
|
+ if(empty($_config['memory']['redis'])) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ $this->_m->init($_config['memory']['redis']);
|
|
|
|
|
+ if(!$this->_m->enable) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ $this->_config = $_config;
|
|
|
|
|
+ }
|
|
|
|
|
+ if($this->_m == null) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ if(!method_exists($this->_m, $method)) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ return call_user_func_array([$this->_m, $method], $params);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // for Developer
|
|
|
|
|
+
|
|
|
|
|
+ private function _getApiParam_Developer($api, $ver) {
|
|
|
|
|
+ $xml = ROOT_PATH.'./data/discuz_restful.xml';
|
|
|
|
|
+ require_once ROOT_PATH.'./source/class/class_xml.php';
|
|
|
|
|
+ $data = file_get_contents($xml);
|
|
|
|
|
+ $xmldata = xml2array($data);
|
|
|
|
|
+ foreach($xmldata['Data']['api'] as $ver => $apis) {
|
|
|
|
|
+ if(!preg_match('/^v(\d+)$/', $ver, $r)) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $this->_parseApis($apis, $ver, '/');
|
|
|
|
|
+ }
|
|
|
|
|
+ if(empty($_ENV['api'][$ver]['/'.$api[0]])) {
|
|
|
|
|
+ $this->error(-109);
|
|
|
|
|
+ }
|
|
|
|
|
+ return $this->apiParam = $_ENV['api'][$ver]['/'.$api[0]];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function _parseApis($apis, $ver, $uriPre = '/') {
|
|
|
|
|
+ if(!is_array($apis)) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ foreach($apis as $uri => $api) {
|
|
|
|
|
+ $k = $uriPre.$uri;
|
|
|
|
|
+ list(, $baseuri) = explode('/', $k);
|
|
|
|
|
+ $baseuri = '/'.$baseuri;
|
|
|
|
|
+ if(!empty($api['script']) && is_string($api['script'])) {
|
|
|
|
|
+ $_ENV['api'][$ver][$baseuri][$k] = [];
|
|
|
|
|
+ $_ENV['api'][$ver][$baseuri][$k] = $api;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $this->_parseApis($api, $ver, $k.'/');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function getAuthSign() {
|
|
|
|
|
+ static $authSign = null;
|
|
|
|
|
+ if($authSign !== null) {
|
|
|
|
|
+ return $authSign;
|
|
|
|
|
+ }
|
|
|
|
|
+ global $_G;
|
|
|
|
|
+
|
|
|
|
|
+ $this->_memory('set', [self::AuthPre.$_G['cookie']['sid'], serialize([
|
|
|
|
|
+ 'auth' => $_G['cookie']['auth'],
|
|
|
|
|
+ 'saltkey' => $_G['cookie']['saltkey'],
|
|
|
|
|
+ 'sid' => $_G['cookie']['sid']
|
|
|
|
|
+ ]), self::AuthTTL]);
|
|
|
|
|
+ return $authSign = authcode($_G['cookie']['sid'], 'ENCODE', md5($_G['config']['security']['authkey']), self::AuthTTL);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function decodeAuthSign(&$session) {
|
|
|
|
|
+ $sid = authcode($this->postParam['_authSign'], 'DECODE', md5($this->_config['security']['authkey']));
|
|
|
|
|
+ if(!$sid) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ $data = $this->_memory('get', [self::AuthPre.$sid]);
|
|
|
|
|
+ if(!$data) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ $cookiepre = $this->_config['cookie']['cookiepre'].substr(md5($this->_config['cookie']['cookiepath'].'|'.$this->_config['cookie']['cookiedomain']), 0, 4).'_';
|
|
|
|
|
+ $session[$cookiepre.'auth'] = $data['auth'];
|
|
|
|
|
+ $session[$cookiepre.'saltkey'] = $data['saltkey'];
|
|
|
|
|
+ $session[$cookiepre.'sid'] = $data['sid'];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|